I would really like to understand why when approaching locating an element the exact same way as previously failing.
NoSuchElementException : Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//span[contains(text(),'Add')]"}
I have also tried to use something like the following but it also failed, so in order for me write a good automation code i need to get my knowledge straight with WebDriverWait, so i would appreciate somebody with knowledge to spend some time on this inquiry.
It does locates if i have xpath like this :
//body/div[#id='root']/div[1]/div[1]/div[1]/div[2]/div[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]
public void clickOnAddVehicleButton() {
wait.until(ExpectedConditions.visibilityOf(addVehicleButton));
vehicles.addVehicleButton.click();
}
I am not new into Java but i am new into automation hence some areas of knowledge is missing, i ha
Base class:
public class BasePage {
protected final WebDriver driver;
protected final WebDriverWait wait;
public BasePage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver,5);
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 10), this);
}
}
The component where that button should be present :
public class Vehicles extends BasePage {
private static Vehicles vehicles;
private Vehicles(WebDriver driver) {
super(driver);
}
#FindBy(xpath = "//span[text(),'Add']")
public WebElement addVehicleButton;
public static Vehicles vehiclesInstance(WebDriver driver) {
return vehicles == null ? vehicles = new Vehicles(driver) : vehicles;
}
public void clickOnAddVehicleButton() {
vehicles.addVehicleButton.click();
}
Function in the service class:
public void addVehicle(String vehicleName, String numberPlate) {
myAccountService.myAccountPage()
.clickOnVehiclesTab();
vehicles.fillInVehicleName(vehicleName)
.fillInVehicleNumberPlate(numberPlate)
.clickOnAddVehicleButton();
}
WebDriverSettings for test :
public class WebDriverSettings {
protected WebDriver driver;
#Before
public void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
loginToDevEnvironment();
}
And finally my test class where i am calling the service method:
public class VehicleServiceTest extends WebDriverSettings {
private VehiclesService vehiclesService;
#Before
public void setUp(){
super.setUp();
CookieService.cookieServiceInstance(driver).acceptCookies();
HomePageService.homePageServiceInstance(driver).clickOnMyAccountTab();
LoginService.loginServiceInstance(driver).login(loginCorrectData());
HomePageService.homePageServiceInstance(driver).clickOnMyAccount();
vehiclesService = VehiclesService.vehiclesServiceInstance(driver);
}
#Test
public void shouldAddVehicle(){
vehiclesService.addVehicle("test-vehicle","test-test");
Assert.assertEquals(1,vehiclesService.getVehicles().listOfAddedVehicles().size());
}
Related
I spent two days on this, and can't seem to find where is the error. In a separate Class, the code is working. In pom.xml I get an error: NullPointerException: Cannot invoke LoginPage.loginCustomer() because this.loginPage is null.
public class _BasePage {
private WebDriver driver;
private WebDriverWait driverWait;
}
with parametrised construktor, getters and setters. Then, a class BankManagerMenu:
public class BankManagerMenu extends _BasePage {
private By addCustomer = By.xpath("/html/body/div/div/div[2]/div/div[1]/button[1]");
public BankManagerMenu(WebDriver driver, WebDriverWait driverWait){
super(driver,driverWait);
}
public boolean addCustomerBtn(){
return this.getDriver().findElement(this.addCustomer).isDisplayed();
}
And a Class LoginPage
public class LoginPage extends _BasePage {
private By customerButton = By.xpath("//*[contains(text(), 'Customer Login']");
private By bankManagerButton = By.xpath("//*[contains(text(), 'Bank Manager Login')]");
public LoginPage(WebDriver driver, WebDriverWait driverWait) {
super(driver, driverWait);
}
public void loginBankManager() {
new WebDriverWait(getDriver(), Duration.ofSeconds(20)).until(ExpectedConditions.elementToBeClickable(bankManagerButton)).click();
}
public void loginCustomer() {
this.getDriver().findElement(this.customerButton).click();
}}
Finally, this is my Test Class
public class TestPage {
private WebDriver driver;
private WebDriverWait driverWait;
private LoginPage loginPage;
private BankManagerMenu bankManagerMenu;
public TestPage(){}
#BeforeClass
public void beforeClass(){
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Raven\\Desktop\\QA\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
// WebDriverWait driverWait = new WebDriverWait(driver, Duration.ofSeconds(15));
driver.navigate().to("https://www.globalsqa.com/angularJs-protractor/BankingProject/#/login");
}
#Test
public void loginAsBankManager(){
this.loginPage.loginBankManager();
// Assert.assertTrue(this.bankManagerMenu.addCustomerBtn());
}}
I am new to Selenium, so basically whenever I ran my test, it would open up the URL which I have mentioned in my test. In my same Test I have also mentioned to fill the username and Password.
But somehow once the browser gets launched and redirect to the URL, it opens up another instance of blank browser failing my script that element not found.
Please help me here.
///////////////////////////////////////////////////////////////////////////
public class TruefillTest extends BaseClass {
public Truefill truefill()
{
WebDriver driver=InitializeDriver();
return new Truefill(driver);
}
#Test
public void userLoginIntoTheSystem()
{
truefill().dashBoard().Url();
truefill().dashBoard().EnterUsername("bjdgfe#swcwr.com");
truefill().dashBoard().EnterPassword("Test1234");
}
///////////////////////////////////////////////
public class Truefill {
private WebDriver driver;
public Truefill(WebDriver driver) {
this.driver=driver;
}
public DashBoardPage dashBoard()
{
return new DashBoardPage(driver);
}
////////////////////////////////////////////////////////////
public class DashBoardPage {
private final WebDriver driver;
By Username= By.xpath("//input[#name='name']");
By Password= By.xpath("//input[contains(#id,'exampleInputPassword1')]");
public DashBoardPage(WebDriver driver) {
this.driver=driver;
}
public void Url()
{
driver.get("https://rahulshettyacademy.com/angularpractice/");
}
public void EnterUsername(String username)
{
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.findElement(Username).sendKeys(username);
}
public void EnterPassword(String password)
{
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.findElement(Password).sendKeys(password);
}
////////////////////////////////////////////////////////////
public class BaseClass {
WebDriver driver;
public WebDriver InitializeDriver()
{
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
return driver;
}
}
Each call to the truefill() method initializes a new instance of WebDriver. Since your test is calling it multiple times, it will start a new browser instance on each line. Instead, store the DashboardPage in a local variable:
#Test
public void userLoginIntoTheSystem() {
DashBoardPage dashBoardPage = truefill().dashBoard();
dashBoardPage.Url();
dashBoardPage.EnterUsername("bjdgfe#swcwr.com");
dashBoardPage.EnterPassword("Test1234");
}
You might also want to use a setup method to initialize the Truefill instance, rather than creating it on demand:
private Truefill truefill;
#BeforeEach
public void initializeTruefill() {
WebDriver driver = InitializeDriver();
truefill = new Truefill(driver);
}
#Test
public void userLoginIntoTheSystem() {
DashBoardPage dashBoardPage = truefill.dashBoard();
dashBoardPage.Url();
dashBoardPage.EnterUsername("bjdgfe#swcwr.com");
dashBoardPage.EnterPassword("Test1234");
}
This assumes JUnit 5. If you're using JUnit 4, the annotation is #Before instead of #BeforeEach.
I have 3 classes like below but when I try to run my test I get NullPointer (TestPage->input1). On debug I spotted that I have a second instantion of driver which is null. Can anyone help me what I did wrong and how to fix it? Shouldn't it work properly?
public class BaseScenario {
protected WebDriver driver;
#BeforeMethod
public void setUp() throws Exception {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Ed\\Desktop\\chromedriver.exe");
driver = new ChromeDriver();
driver.get("http://toolsqa.com/automation-practice-form/");
}
#AfterMethod
public void TearDown() {
driver.quit();
}
}
'
public class TestsPage {
WebDriver driver;
public TestsPage(WebDriver driver)
{
this.driver=driver;
}
public void input1(){
driver.findElement(By.xpath("//*[#id='content']/form/fieldset/div[1]/input[1]")).sendKeys("Kuba");;
}
public WebElement input2(){
WebElement input2 = driver.findElement(By.xpath("//*[#id='content']/form/fieldset/div[1]/input[2]"));
return input2;
}
}
'
public class Tests extends BaseScenario{
TestsPage pagee = new TestsPage(driver);
#Test
public void TC1() throws Exception {
pagee.input1();
pagee.input2().sendKeys("Chudy");
}
}
I want use a common WebDriver instance across all my TestNG tests by extending my test class to use a base class as shown below but it doesn't seem to work :
public class Browser {
private static WebDriver driver = new FirefoxDriver();
public static WebDriver getDriver()
{
return driver;
}
public static void open(String url)
{
driver.get(url);
}
public static void close()
{
driver.close();
}
}
I want to use the WebDriver in my test class as shown below, but I get the error message :
The method getDriver() is undefined for the type GoogleTest:
public class GoogleTest extends Browser
{
#Test
public void GoogleSearch() {
WebElement query = getDriver().findElement(By.name("q"));
// Enter something to search for
query.sendKeys("Selenium");
// Now submit the form
query.submit();
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 5 seconds
WebDriverWait wait = new WebDriverWait(getDriver(), 30);
// wait.Until((d) => { return d.Title.StartsWith("selenium"); });
//Check that the Title is what we are expecting
assertEquals("selenium - Google Search", getDriver().getTitle().toString());
}
}
The problem is that your getDriver method is static.
Solution #1: Make method non-static (this will either need to make the driver variable non-static as well, or use return Browser.getDriver(); )
public WebDriver getDriver() {
return driver;
}
Or, call the getDriver method by using Browser.getDriver
WebElement query = Browser.getDriver().findElement(By.name("q"));
You need to start your driver, one of many solution is to try #Before to add, Junit will autorun it for you.
public class Browser {
private WebDriver driver;
#Before
public void runDriver()
{
driver = new FirefoxDriver();
}
public WebDriver getDriver()
{
return driver;
}
public void open(String url)
{
driver.get(url);
}
public void close()
{
driver.close();
}
}
Hi i have a global class as belows:
public class Global
{
public WebDriver driver=null;
public WebDriverWait wait=null;
public Global()
{
BrowserInitializer obj=new BrowserInitializer();
obj.initialize();
}
}
I have another class called browser initializer where i want to initialize the driver instance to firefox as below:
public class BrowserInitializer extends Global
{
public void initialize()
{
driver=new FirefoxDriver();
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 5000);
}
}
I have testNG class where i want to run some test as belows :
public class TestNG1
{
Global globalObj=new Global();
#Test
public void login()
{
globalObj.driver.get("someURL");
globalObj.driver.findElement(By.id("someid")).sendKeys("someusername");
globalObj.driver.findElement(By.id("someid")).sendKeys("somepassword");
globalObj.driver.findElement(By.id("someid")).submit();
}
}
Now i am getting error like :
org.testng.TestNGException:
Cannot instantiate class unitTest.myTest.TestNG1
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:38)
at org.testng.internal.ClassHelper.createInstance1(ClassHelper.java:387)
at org.testng.internal.ClassHelper.createInstance(ClassHelper.java:299)
at org.testng.internal.ClassImpl.getDefaultInstance(ClassImpl.java:110)
at org.testng.internal.ClassImpl.getInstances(ClassImpl.java:186)
at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:120)
at org.testng.TestRunner.initMethods(TestRunner.java:409)
at org.testng.TestRunner.init(TestRunner.java:235)
at org.testng.TestRunner.init(TestRunner.java:205)
at org.testng.TestRunner.<init>(TestRunner.java:160)
at org.testng.remote.RemoteTestNG$1.newTestRunner(RemoteTestNG.java:141)
at org.testng.remote.RemoteTestNG$DelegatingTestRunnerFactory.newTestRunner(RemoteTestNG.java:271)
at org.testng.SuiteRunner$ProxyTestRunnerFactory.newTestRunner(SuiteRunner.java:577)
at org.testng.SuiteRunner.init(SuiteRunner.java:157)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1299)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1286)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.testng.internal.ObjectFactoryImpl.newInstance(ObjectFactoryImpl.java:29)
... 21 more
Caused by: java.lang.StackOverflowError
at unitTest.myTest.Global.<init>(Global.java:12)
at unitTest.myTest.BrowserInitializer.<init>(BrowserInitializer.java:6)
at unitTest.myTest.Global.<init>(Global.java:14)
but when i am initializing the driver instance in the constructor of the Global class i am able to run my test. what seems to be the problem? am i going wrong somewhere in the concepts of java?
You have infinite recursion when calling Global's constructor. Your initialize() is perfectly fine.
public Global()
{
BrowserInitializer obj=new BrowserInitializer();
obj.initialize();
}
BrowserInitializer is a Global.
So Global's contructor calls BrowserInitializer's constructor (which calls super's i.e Global's constructor again)
Use something like:
public class BrowserInitializer extends Global
{
BrowserInitializer(){
super();
this.initialize();
}
public void initialize()
{
driver=new FirefoxDriver();
driver.manage().window().maximize();
wait=new WebDriverWait(driver, 5000);
}
}
//In test class
Global globalObj=new BrowserInitializer();
I woudl approach this in a different way, and use a #BeforeTes annotation;
Create a new webdriver class which extends Firefox driver;
public class MyFirefoxDriver extends FirefoxDriver {
private WebDriverWait wait;
private WebDriver driver;
public MyFirefoxDriver()
{
super();
this.manage().window().maximize();
wait = new WebDriverWait(this, 5000);
}
public WebDriverWait getWebDriverWait() {
return wait;
}
}
Your test would then look like this;
public class TestNG1
{
private MyFirefoxDriver driver;
#BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
#Test
public void login()
{
driver.get("someURL");
driver.findElement(By.id("someid")).sendKeys("someusername");
driver.findElement(By.id("someid")).sendKeys("somepassword");
driver.findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = driver.getWebDriverWait();
}
#AfterTest
public void tearDown() {
driver.quit();
}
}
I would be tempted to then further create a base test class;
public abstract class TestNGBase
{
private MyFirefoxDriver driver;
public MyFirefoxDriver getDriver() {
return driver;
}
#BeforeTest
public void setUp() {
driver = new MyFirefoxDriver();
}
#AfterTest
public void tearDown() {
driver.quit();
}
}
In which case you test would then look like this;
public class TestNG1 extends TestNGBase
{
#Test
public void login()
{
getDriver().get("someURL");
getDriver().findElement(By.id("someid")).sendKeys("someusername");
getDriver().findElement(By.id("someid")).sendKeys("somepassword");
getDriver().findElement(By.id("someid")).submit();
//To access the wait;
WebDriverWait wait = getDriver().getWebDriverWait();
}
}