Reputation: 546
So, I have a class A and it has a (public static WebElement element1, element2).
public class myClass {
public static WebElement element1, element2;
public myClass(){
WebDriver driver = new FirefoxDriver();
this.element1 = driver.findElement(By.id("button"));
this.element2 = driver.findElement(By.id("text"));
}
}
And then I have a test class where it has a method called @Test public void testClassA.
@Test
public void testClassA(){
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}
Questions is I am getting org.openqa.selenium.NoSuchElementException: Unable to locate element:{} error. I think my error is happening because the element2 is located in the next page, it shows up after clicking the button. What should I do in my code so that when I assign both elements to findBy method the test is going through the first click and then sendKeys to element2?
Upvotes: 1
Views: 437
Reputation: 2301
The way you have written the code will break in scenarios where elements are dynamic and also on page navigation.
This is not a good practice to find the webelement in different class altogether and use the object of that class in your test class.
As you can see in code: myClass m = new myClass();
, when object of myClass
is created, the constructor is triggered and driver finds both the element1
and element2
at once. And, since element2 is still not displayed, it throws an exception.
I don't know what prompted you to follow this practice, instead find the webelement only when you actually need it. There seems to be many alternative and it depends on how you want to design your code.
More Standard practice(I guess so):
Good Reference: http://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html
Upvotes: 1
Reputation: 1462
You can use webdriver implicitwait to wait for the elements on the page to load for a certain period of time.
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
As you can see in the above code i used 8 seconds for the elemnets on the page to load. Read more about wait in Webdriver
Use a try catch block to handle the exception.
@Test
public void testClassA(){
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
try{
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}catch(NoSuchElementException e){
e.printStackTrace();
}
}
Upvotes: 1
Reputation: 5819
As you mentioned that the element2 is present in the next page, you have to wait till the new page loads. Without this wait, if you try finding the element2, it will throw an exception as the element is not found on the current page before the page change.
Solutions:
1) Add a Explicit wait after the element1 click() method. You can wait till the element2 is present after the click().
m.element1.click();
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("text")));
m.element2.sendKeys("input something");
2) Simple but I would not recommend this. Use Thread.sleep() to wait for the new page to load.
3) Use Page Object Design Pattern.
Upvotes: 1