I've just started using Java today and have created some tests but I want to use JavascriptExecutor to be able to report tests passing or failing to Sauce Labs. I've imported the library I believe I need but it doesn't recognise the import either way. I believe I am doing it correctly but evidently I'm not and would like some help to understand where I'm going wrong.
My code looks like this:
package tests;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import pageobjects.Login;
import org.junit.jupiter.api.extension.TestWatcher;
import org.openqa.selenium.JavascriptExecutor;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class TestLogin extends BaseTest {
private Login login;
#RegisterExtension
public SauceTestWatcher watcher = new SauceTestWatcher();
#Before
public void setUp() {
login = new Login(driver);
}
#Test
public void succeeded() {
login.with("tomsmith", "SuperSecretPassword!");
assertTrue("success message not present",
login.successMessagePresent());
}
#Test
public void failed() {
login.with("tomsmith", "bad password");
assertTrue("failure message wasn't present after providing bogus credentials",
login.failureMessagePresent());
}
#Test
public void failed2() {
login.with("tomsmith", "bad password");
assertFalse("success message was present after providing bogus credentials",
login.successMessagePresent());
}
public class SauceTestWatcher implements TestWatcher {
#Override
public void testSuccessful(ExtensionContext context) {
driver.executeScript("sauce:job-result=passed");
driver.quit();
}
#Override
public void testFailed(ExtensionContext context, Throwable cause) {
driver.executeScript("sauce:job-result=failed");
driver.quit();
}
}
}
I use import org.openqa.selenium.JavascriptExecutor; to get and I'm referencing it at the bottom: driver.executeScript("sauce:job-result=failed"); or the passed just above it.
Invalidating cache and restarting resolved. Also changed the code slightly.
((JavascriptExecutor) driver).executeScript("sauce:job-result=passed");
This resolved my issue
Related
i am rather new to coding in general and Have gotten most of my code from my instructor who is on vacation at the moment
The problem i am having is i made my OR.properties and OR_Propertiesloader class
Inside the OR_Propertiesloader class i am able to print out the xpath
But when i put it into a test script it read the value as NULL
Here is my code so far
package com.reuseables;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Properties;
public class OR_PropertiesLoader {
private static Properties OR_P_Obj;
private static String userNameBox;
public static String userNameBoxEle(){
return userNameBox;
}
public static void load_OR_Properties() throws FileNotFoundException {
try {
OR_P_Obj = new Properties();
OR_P_Obj.load(
new FileInputStream(
new File(
System.getProperty("user.dir") +
"/src/test/resources/ObjectRepository/OR.properties")));
}catch (Exception e){
System.out.println("Unable to read property file. Pls check the location of the file");
}
}
public static String getProperty(String propertyName) {
return OR_P_Obj.getProperty(propertyName);
}
public static void initialize_OR_Configurations() throws FileNotFoundException {
load_OR_Properties();
userNameBox = getProperty("userNameBox");
}
public static void main(String[] args) throws FileNotFoundException {
OR_PropertiesLoader.initialize_OR_Configurations();
System.out.println(OR_PropertiesLoader.userNameBoxEle());
}
}
The line im trying to use in my properties file is
userNameBox =//input[#id='txtUsername']
And this is the part of the test script im trying to throw the xpath into
package com.login.tests;
import com.reuseables.BaseTest;
import com.reuseables.ConfigPropertiesLoader;
import com.reuseables.OR_PropertiesLoader;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.Test;
public class personalDetailsValidationScenario extends BaseTest {
#Test
public void ValidatePositivePersonalDetailsScenario () throws InterruptedException {
// Go to URL
driver.get(ConfigPropertiesLoader.getApplicationURL());
//Enter Username
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle()));
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle())).clear();
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle())).sendKeys(Username);
...
I previously tried to throw a " System.out.println(OR_PropertiesLoader.userNameBoxEle());" but it also gave me a null before failing the test
If anybody is able to lend me a hand with this is would greatly appreciate it!
#pcalkins Oh my god, thank you! the god damn config was not loading
Im pretty sure i didnt do the fix exactly the way you meant it, as i said im seemingly not fully understanding the way java works sometimes as i mentioned im pretty new at coding
But basically the change i made was to the test script itself
package com.login.tests;
import com.reuseables.BaseTest;
import com.reuseables.ConfigPropertiesLoader;
import com.reuseables.OR_PropertiesLoader;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.io.FileNotFoundException;
public class personalDetailsValidationScenario extends BaseTest {
#Test
public void ValidatePositivePersonalDetailsScenario() throws InterruptedException, FileNotFoundException {
OR_PropertiesLoader.initialize_OR_Configurations(); // <<<<This is the change i made>>>>
// Go to URL
driver.get(ConfigPropertiesLoader.getApplicationURL());
//Enter Username
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle()));
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle())).clear();
driver.findElement(By.xpath(OR_PropertiesLoader.userNameBoxEle())).sendKeys(Username);
I'll figure out how Mystical secrets of Java one day
I am getting the error below. I am new to Java and thus any help would be appreciated.
Cannot invoke "org.openqa.selenium.WebDriver.get(String)" because "this.driver" is null
Please see the code below:
package steps;
import io.cucumber.java.en.Given;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.After;
import org.junit.Before;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class hotelBookingFormPage {
public WebDriver driver;
#Before
public void startBrowser() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
}
#After
public void closeBrowser() {
driver.close();
driver.quit();
}
#Given("I navigate to the hotel booking form page")
public void iNavigateToTheHotelBookingFormPage() {
driver.get("http://hotel-test.equalexperts.io/");
}
Any help would be appreciated.
import org.junit.After;
import org.junit.Before;
With this you're importing the JUnit hook annotations, not the Cucumber ones. So Cucumber doesn't know you want to run the annotated methods before and after each scenario.
Cucumbers annotations are in a different package:
import io.cucumber.java.en.Before;
import io.cucumber.java.en.After;
The casting of the Webdriver interface with Chromedriver has only been declared in your #Before step (where it is not used), the other steps are unaware. Amend to the following:
public class hotelBookingFormPage {
public WebDriver driver = new ChromeDriver();
#Before
public void startBrowser() {
WebDriverManager.chromedriver().setup();
}
#After
public void closeBrowser() {
driver.close();
driver.quit();
}
#Given("I navigate to the hotel booking form page")
public void iNavigateToTheHotelBookingFormPage() {
driver.get("http://hotel-test.equalexperts.io/");
}
I've been trying to transfer my restassured tests using testng over to cucumber and I've almost cracked it however the assertion has thrown me a little bit. This issue I have is the body in my assertion is throwing this error.
java: cannot find symbol
symbol: method body(java.lang.String,org.hamcrest.Matcher<java.lang.String>)
location: class stepdefs.articlesCucumberTests
Here is my current working tests.
import static io.restassured.RestAssured.*;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
import static org.hamcrest.Matchers.*;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.path.json.JsonPath;
import org.testng.annotations.Test;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
#SuppressWarnings("unchecked")
public class articlesTestNg extends enablers {
//Checks articles individual ID's.
#Test(dataProvider = "getId")
public void TestAllArticles(String articlesId) {
given().
given().log().all().and().
pathParam("id", articlesId).
when().
get(singleArticles).
then().
assertThat().
statusCode(200).
body(("id"), equalTo(articlesId));
}
//Checks the whole content of the json file using an expected outcome in the project structure.
#Test
public void GetArticlesJson() {
JsonPath expectedJson = new JsonPath(new File(pathJson));
given().
when().
get(allArticles).
then().
assertThat().
statusCode(200).
and().
body("", hasItem(expectedJson.getMap("")));
}
Here is my so far attempt at the cucmber tests in the I will receive an individual article the body is throwing the error. Is there a better way to do this?
package stepdefs;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.Assertions;
import org.testng.Assert;
import org.testng.annotations.Test;
import skySportsPages.enablers;
import static io.restassured.RestAssured.baseURI;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
public class articlesCucumberTests extends enablers {
private Response response;
#Test
#Given("I have a set of articles containing individual ID's")
public void i_have_a_set_of_articles_containing_individual_id_s() {
RestAssured.baseURI = singleArticles;
System.out.println(baseURI);
}
#Test(dataProvider = "getId")
#When("I get an the article ID")
public void i_get_an_the_article_id(String articlesId) {
given().
given().log().all().and().
pathParam("id", articlesId).
when().
get(singleArticles);
}
#Test
#Then("I will receive an individual article")
public void i_will_receive_an_individual_article(String articlesId) {
Assert.assertEquals(body(("id"), equalTo(articlesId)));
}
#Test
#Given("I have a set of articles")
public void i_have_a_set_of_articles(String articlesId) {
}
#Test
#When("I get the list of articles")
public void i_get_the_list_of_articles() {
}
#Test
#Then("It will match the json file")
public void it_will_match_the_json_file() {
}
}
No, I think we don't use #Test annotation in cucumber step. You should check out at toolqa for more tutorials.
Error is here because Assert.assertEquals should have two parameters, in your case you have only one body(("id"), equalTo(articlesId)) that may return boolean, so check first what you have just performing:
#Test
#Then("I will receive an individual article")
public void i_will_receive_an_individual_article(String articlesId) {
body(("id"), equalTo(articlesId));
}
And then try to change to:
Assert.assertTrue(body(("id"), equalTo(articlesId)));
I have been trying to make LeanFT html reports work with my Selenium/Junit framework, however so far without any joy.
I have searched the topic multiple times on different forums incl. HP official materials and tried all setup methods that I could find.
An XML runresults file is still generated when using a custom Selenium/LeanFT framework.
I create a LeanFT Testing Project project using JUnit as my framework and Selenium as SDK. I also add relevant Selenium jars.
LeanFT version is 14.0.2816.0.
I am conscious of this issue: https://community.softwaregrp.com/t5/UFT-Practitioners-Forum/HTML-report-not-generated-in-custom-framework-using-LeanFT/td-p/1614027 .
I would be grateful, if someone could explain where I am making a mistake here or if the software version is the problem here. Any help is very much appreciated.
The actual setup contains more abstractions, is generally more complex and runs as a jar file, but I have simplified the code for the purpose of this topic as the outcome of both setups is the same - a runresults.xml and no html:
Test Class:
import com.hp.lft.report.CaptureLevel;
import com.hp.lft.report.ModifiableReportConfiguration;
import com.hp.lft.report.Reporter;
import com.hp.lft.sdk.ModifiableSDKConfiguration;
import com.hp.lft.sdk.SDK;
import com.hp.lft.sdk.web.Browser;
import com.hp.lft.sdk.web.BrowserDescription;
import com.hp.lft.sdk.web.BrowserFactory;
import com.hp.lft.sdk.web.BrowserType;
import core.Selenium;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.*;
import java.io.File;
import java.net.URI;
public class SeleniumTest extends Selenium {
WebDriver driver;
Browser browser;
public SeleniumTest() {
//Change this constructor to private if you supply your own public constructor
}
#BeforeClass
public static void setUpBeforeClass() throws Exception {
instance = new SeleniumTest();
globalSetup(SeleniumTest.class);
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
globalTearDown();
}
#Before
public void setUp() throws Exception {
ModifiableSDKConfiguration sdkConfig = new ModifiableSDKConfiguration();
sdkConfig.setServerAddress(new URI("ws://localhost:5095"));
SDK.init(sdkConfig);
ModifiableReportConfiguration reportConfig = new ModifiableReportConfiguration();
reportConfig.setOverrideExisting(true);
reportConfig.setTargetDirectory("C:\\Users\\user\\IdeaProjects\\LeanFT_Selenium\\RunResults");
reportConfig.setReportFolder("LastRun");
reportConfig.setTitle("Summary");
reportConfig.setDescription("Description");
reportConfig.setSnapshotsLevel(CaptureLevel.All);
Reporter.init(reportConfig);
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File
("C:\\Program Files (x86)\\HP\\Unified Functional Testing\\Installations\\Chrome\\Agent.crx"));
System.setProperty("webdriver.chrome.driver",
"C:\\HP_Reporting\\Webdriver\\chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(options);
browser = BrowserFactory.attach(new BrowserDescription.Builder()
.type(BrowserType.CHROME).build());
}
#After
public void tearDown() throws Exception {
driver.quit();
browser = null;
Reporter.generateReport();
SDK.cleanup();
}
#Test
public void test() throws Exception {
driver.get("https://www.google.co.uk/");
}
}
Selenium Class:
import com.hp.lft.report.Status;
import com.hp.lft.unittesting.UnitTestBase;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
public class Selenium extends UnitTestBase{
protected static Selenium instance;
public static void globalSetup(Class<? extends Selenium> testClass) throws Exception {
if (instance == null)
instance = testClass.newInstance();
instance.classSetup();
}
#Before
public void beforeTest() throws Exception {
testSetup();
}
#After
public void afterTest() throws Exception {
testTearDown();
}
public static void globalTearDown() throws Exception {
instance.classTearDown();
getReporter().generateReport();
}
#ClassRule
public static TestWatcher classWatcher = new TestWatcher() {
#Override
protected void starting(org.junit.runner.Description description) {
className = description.getClassName();
}
};
#Rule
public TestWatcher watcher = new TestWatcher() {
#Override
protected void starting(org.junit.runner.Description description) {
testName = description.getMethodName();
}
#Override
protected void failed(Throwable e, org.junit.runner.Description description) {
setStatus(Status.Failed);
}
#Override
protected void succeeded(org.junit.runner.Description description) {
setStatus(Status.Passed);
}
};
#Override
protected String getTestName() {
return testName;
}
#Override
protected String getClassName() {
return className;
}
protected static String className;
protected String testName;
}
Libraries
TL;DR
The report is only generated in 14.00 by extending UnitTestBase. To have the report generated with a custom automation framework, you must upgrade to at least LeanFT 14.01 (latest one at the time of writting is 14.02 though).
Oh, and just for clarification: this issue has nothing to do with Selenium. You'd have the same behavior in C# LeanFT SDK using NUnit 3, for example.
Details
What is a custom automation framework in this context?
When I say custom automation framework I mean any framework that does the SDK and Reporter initialization and cleanup itself.
LeanFT does all the magic through its engine. To tell a custom framework to connect to the engine, you need perform the following steps:
at the beginning of a test suite:
SDK.init();
Reporter.init(); // This is not for the engine, but for the HTML report generation
at the end of a test suite
Reporter.generateReport();
SDK.cleanup();
When you are using the builtin templates, you'll notice that a UnitTestClassBase class is automatically created, that extends from UnitTestBase and that your LeanFtTest class extends from this UnitTestClassBase.
By doing so you are initializing the SDK and the Reporter in a very specific way, which is the reason why with this initialization the HTML report is generated. If you were to reproduce this specific way in your custom framework, you'll also have the HTML report generated. If you are curious, you can check the contents of the UnitTestBase.class file to see what it does.
You are extending from UnitTestBase. Why is it not working?
As mentioned in my comments, you are actually doing the SDK and Reporter initialization twice, once by extending the UnitTestBase (which, as I described above, does that initialization already) and the second time in your setUp method.
Since you are using LeanFT 14.00, you should let the UnitTestBase do the initialization, cleanup and report generation. This means that your Test Class file should be changed to no longer include the init of the SDK and Reporter, as follows:
import com.hp.lft.report.CaptureLevel;
import com.hp.lft.report.ModifiableReportConfiguration;
import com.hp.lft.report.Reporter;
import com.hp.lft.sdk.ModifiableSDKConfiguration;
import com.hp.lft.sdk.SDK;
import com.hp.lft.sdk.web.Browser;
import com.hp.lft.sdk.web.BrowserDescription;
import com.hp.lft.sdk.web.BrowserFactory;
import com.hp.lft.sdk.web.BrowserType;
import core.Selenium;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.*;
import java.io.File;
import java.net.URI;
public class SeleniumTest extends Selenium {
WebDriver driver;
Browser browser;
public SeleniumTest() {
//Change this constructor to private if you supply your own public constructor
}
#BeforeClass
public static void setUpBeforeClass() throws Exception {
instance = new SeleniumTest();
globalSetup(SeleniumTest.class);
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
globalTearDown();
}
#Before
public void setUp() throws Exception {
/*
This will not work in LeanFT 14.00, so we are commenting it out
ModifiableSDKConfiguration sdkConfig = new ModifiableSDKConfiguration();
sdkConfig.setServerAddress(new URI("ws://localhost:5095"));
SDK.init(sdkConfig);
ModifiableReportConfiguration reportConfig = new ModifiableReportConfiguration();
reportConfig.setOverrideExisting(true);
reportConfig.setTargetDirectory("C:\\Users\\user\\IdeaProjects\\LeanFT_Selenium\\RunResults");
reportConfig.setReportFolder("LastRun");
reportConfig.setTitle("Summary");
reportConfig.setDescription("Description");
reportConfig.setSnapshotsLevel(CaptureLevel.All);
Reporter.init(reportConfig);
*/
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File
("C:\\Program Files (x86)\\HP\\Unified Functional Testing\\Installations\\Chrome\\Agent.crx"));
System.setProperty("webdriver.chrome.driver",
"C:\\HP_Reporting\\Webdriver\\chromedriver.exe");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new ChromeDriver(options);
browser = BrowserFactory.attach(new BrowserDescription.Builder()
.type(BrowserType.CHROME).build());
}
#After
public void tearDown() throws Exception {
driver.quit();
browser = null;
//Reporter.generateReport();
//SDK.cleanup();
}
#Test
public void test() throws Exception {
driver.get("https://www.google.co.uk/");
}
}
But I need to configure the SDK and the Report. How can I achieve that in LeanFT 14.00?
The SDK and the Reporter can be configured in two ways:
At initialization, as you attempted to do through the ModifiableSDKConfiguration and ModifiableReportConfiguration
or
In the test settings file (resources/leanft.properties). You can see plenty details in the official help.
You can manipulate some report settings at runtime as well, through the Reporter API:
Set the report level: Reporter.setReportLevel(ReportLevel.All);
Set the snapshot capture level Reporter.setSnapshotCaptureLevel(CaptureLevel.All);
Even if you initialized the SDK and the Reporter through the base class, you can still add custom report events in the report (these work: Reporter.reportEvent();, Reporter.startReportingContext();, Reporter.startTest();, etc.)
I have attached POM, BaseTest and Test classes. Im getting NullPointerException for the below code on trying to run it as TestNG test by right clicking on the project. Please could suggest?
POM Class:
package pom;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Introduction
{
#FindBy(xpath="//a[text()='Hello. Sign In']")
WebElement signInLink;
public Introduction(WebDriver driver)
{
PageFactory.initElements(driver, this);
}
public void signIn()
{
signInLink.click();
}
}
BaseTest Class:
package scripts;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.*;
public class BaseTest
{
public WebDriver driver;
#BeforeSuite
public void preCondition()
{
driver= new FirefoxDriver();
driver.get("https://www.walmart.com/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#AfterSuite
public void postCondition()
{
driver.close();
}
}
Test Class:
package scripts;
import org.testng.annotations.Test;
import pom.Introduction;
public class SignIn extends BaseTest
{
#Test
public void validSignIn()
{
Introduction i= new Introduction(driver);
i.signIn();
}
}
Your code has a few issues.
You are instantiating your webdriver in a #BeforeSuite. This causes your webdriver instance to be created ONLY once per <suite> tag. So all other #Test methods will always get a NullPointerException because the #BeforeSuite annotated method doesn't get executed the second time.
You are resorting to using implicit timeouts. Please don't use implicit timeouts. You can read more about the evils of implicit waits in this SO post.
So to get started, I would suggest that change your test code to something like below
BaseTest.java
package scripts;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.*;
public class BaseTest {
private static ThreadLocal<WebDriver> driver = new ThreadLocal<>();
#BeforeMethod
public void preCondition() {
driver.set(new FirefoxDriver());
driver.get().get("https://www.walmart.com/");
}
#AfterMethod
public void postCondition() {
driver.get().quit();
}
public final WebDriver driver() {
return driver.get();
}
}
SignIn.java
package scripts;
import org.testng.annotations.Test;
import pom.Introduction;
public class SignIn extends BaseTest {
#Test
public void validSignIn() {
Introduction i = new Introduction(driver());
i.signIn();
}
}
Here what we have done is chose to use #BeforeMethod and #AfterMethod for instantiation and cleanup of webdriver, because these methods are guaranteed to be executed before and after every #Test method. We then went on to using ThreadLocal variants of Webdriver because ThreadLocal ensures that every thread gets its own copy of webdriver, so that you can easily start running your tests in parallel. This is right now not a problem, but very soon you will face this issue as you start building upon your implementation. You can read more about how to resort to parallel executions using TestNG by reading this blog post of mine.