This is kinda follow-up for my question Test causing error occasionally. I initialize my driver
public class TestSuite {
public static WebDriver driver;
#BeforeClass
public static void setUpClass() {
driver = new FirefoxDriver();
}
public class FluentDriver extends TestSuite {
public static WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(300, TimeUnit.SECONDS)
.pollingEvery(50, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
return element;
}
;
}
But this this not handling the script which certainly is on the page, but I can't access the source of it.
FluentDriver.fluentWait(By.id("id")).click();
FluentDriver.fluentWait(By.xpath("//a[starts-with(#href,'/problematic_url.html')]")).click();
FluentDriver.fluentWait(By.className("green_true")).click();
Clicking the "id" pulls out a submenu, where the problematic url is. On webpage source (Ctrl+U) the url is present the whole time.
I got this working by adding Javascript enabling Firefox profile on driver. Then I use the FluentDriver solution. It works most of the time.
Related
I am using TestNG with java to execute my scripts.
I have a fixed tab bar with 5 elements fixed for all time once the user logged in to the application.
I am able to execute the script by clicking on the first element from the list, but for the second time when I try to click on another element from the tab bar it is failing continuously. I tried adding explicit waits, but is not helping me either.
Here is a snippet of my code:
afterLogin.java
public class afterLogin {
WebDriver driver;
WebDriverWait wait;
#FindBy(xpath="//*[#id=\"root\"]/div/div[2]/div/div[1]/div[1]/div[3]")
WebElement button1;
#FindBy(xpath = "//*[#id=\"root\"]/div/div[2]/div/div[1]/div[1]/div[2]")
WebElement button2;
public afterLogin(WebDriver driver){
this.driver = driver;
wait = new WebDriverWait(driver,Duration.ofSeconds(300));
}
public void clickButton1() {
wait.until(ExpectedConditions.visibilityOf(button1);
button1.click();
}
public void clickButton2(){
wait.until(ExpectedConditions.visibilityOf(button2));
button2.click();
}
}
testCase1.java
#Test
public void init() throws Exception {
afterLogin obj = PageFactory.initElements(driver, afterLogin.class);
obj.clickButton1();
}
testCase2.java
#Test
public void init() throws Exception {
afterLogin obj = PageFactory.initElements(driver, afterLogin.class);
obj.clickButton2(); /////THIS IS FAILING
}
I was able to solve this by using Thread.sleep(1000). I will try to update my code to use Implicit waits, but this solves the purpose for now.
I have a few que.
public class LoginPage {
private WebDriver driver;
#FindBy(xpath = "//*[#id=\"textfield-1015-inputEl\"]")
private WebElement loginFiled;
#FindBy(xpath = "//*[#id=\"textfield-1017-inputEl\"]")
private WebElement passwordField;
#FindBy(xpath = "//*[#id=\"button-1021-btnIconEl\"]")
private WebElement signButton;
public LoginPage(WebDriver driver) {
this.driver=driver;
}
public void init(){
PageFactory.initElements(driver, this);
}
public void singIntoSystemAsUser(String login,String password) {
try {
Logger logger = Logger.getLogger(LoginPage.class.getName());
logger.log(Level.INFO,"zdes");
loginFiled.sendKeys(login);
passwordField.sendKeys(password);
signButton.click();
}
catch (Exception e){
Logger logger = Logger.getLogger(LoginPage.class.getName());
logger.log(Level.INFO,e.getMessage());
}
}
#BeforeMethod(alwaysRun = true)
public void browserSetup() {
options = new ChromeOptions();
options.setPageLoadStrategy(PageLoadStrategy.NONE);
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(5000,
TimeUnit.MILLISECONDS);
driver.manage().timeouts().pageLoadTimeout(5000,
TimeUnit.MILLISECONDS);
driver.manage().timeouts().setScriptTimeout(5000,
TimeUnit.MILLISECONDS);
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
driver.get("https://junior.webquik.ru/");
loginPage = new LoginPage(driver);
homePage = new HomePage(driver);
}
#Test(description = "Sign into account")
public void signIntoSystem() throws InterruptedException {
loginPage.singIntoSystemAsUser("U0191767","06258");
Assert.assertEquals(driver.getTitle(),"webQUIK 7.6.2");
}
After launch test a got the exception stale element reference: element is not attached to the page document
I have this exception a few weeks ago and i fix this just by add implicitlyWait,but now i added pageObject patter to my project
and its refuse to work,can you guys tell me what the damn hell wrong with program????
Also a tried change something by removing #FindBy from LoginPage class and add WebElemtn .. = driver.findElement instead,
and i got exception whos telling me that he cant find element on page,
but if ш manually go on page,press f12 and try to find this element i will find it.Pls help
When i tried to fix errors i got the new problem, i got the exception whos tells me that my loginPage object is null, i change code a little bit,and a give to this object the memory,but i have exception anyways.
When I use POM class, getting Nullpointer exception. however if I use driver.findelement directly in class, it works correct. Can you please pour in your thougts to fix this?
#Test
public void testFlow() throws InterruptedException {
UtilityClass.setUpPath();
WebDriver driver = new ChromeDriver();
try{
driver.navigate().to("http://demo.guru99.com/payment-gateway/check_credit_balance.php");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.id("card_nmuber")).sendKeys("1234567891234567");
System.out.println(driver.findElement(By.id("card_nmuber")).getAttribute("value"));
HomePage hp = new HomePage(driver);
hp.clickSubmit();
}
finally{
driver.quit();
}
}
public class HomePage {
WebDriver driver;
public HomePage(WebDriver driver){
this.driver = driver;
}
#FindBy(name = "submit")
private WebElement signIn ;
public void clickSubmit() {
signIn.click(); }} }}
Error: java.lang.NullPointerException
Your page object field is not associated with a WebElement. You need to add a constructor that would call
PageFactory.initElements(driver, this)
Your constructor of course has to take WebDriver as an argument
In HomePage class:
By signIn = By.name("submit");
public void clickSubmit() {
driver.findElement(signIn).click(); }}
Found the correct way of using POM without Page factory. This is working code
I started encountering problems when I use static objects reference for WebDriver and run the tests in parallel.
public static WebDriver driver;
Hence I decided to use non-static object reference for the WebDriver.
private WebDriver driver;
Now when I use POM with Page Factory, my understanding is that everytime I create a Test I will have to be creating a new Object in the test class as shown below.
/* Constructor in the Page Object class */
private WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
2 testcases as shown below in the same class.
private LoginPage loginPage;
#Test
public void testCase1() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
#Test
public void testCase2() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
My question here is a
Am I right in creating page object for every test cases?
Is there any way I can optimize this? Because One doubt I got is that non-static object reference may be getting overridden and causing problems in one of the methods if I run them in parallel.
Sorry if my query is naive. Any help would be appreciated.
You do not need to initialize it again. Also, initialize the pages in #BeforeTest rather than in test cases.
Here i would like to give you example of Page object model. Hope you can relate this.
My Main test:
#Before
public void SelectBrowser(){
driver = WebUtils.SelectBrowser(driver,"Chrome");
}
#Test
public void LoginToGmail() throws InterruptedException{
//WebDriver driver = new FirefoxDriver();
//MAximize the Screen
driver.manage().window().maximize();
//Go to Gmail Login Page
SignInPage SignInPage = new SignInPage();
WebUtils.GoToSignInPageForPropertyFile(driver, "URL");
//Click on Next
SignInPage.ClickToLogin(driver, By.cssSelector("input[id='next']"));
Now Supporting class:
GoToSignInPageForPropertyFile method will be in WebUtils
Whatever i write in Webutils will be used by each page object class.
For e.g.
public class WebUtils {
public static pageobject.SignInPage GoToSignInPageForPropertyFile(WebDriver driver, String URL) {
ReadFileData File = new ReadFileData();
Properties Values = File.ReadFile();
driver.get(Values.getProperty("URL"));
return PageFactory.initElements(driver, pageobject.SignInPage.class);
}
}
Now the method ClickToLogin is defined under SignInPage class as:
public class SignInPage {
public EmailViewPage ClickToLogin(WebDriver driver, By by) {
WebUtils.Click(driver, by);
return PageFactory.initElements(driver, EmailViewPage.class);
}
}
Which will further be in Webutils
public class WebUtils {
public static void Click(WebDriver driver, By by) {
WebElement Element = driver.findElement(by);
Element.click();
}
}
I'm trying to test one specific Selenium's Actions class method, which is as below.
public Actions sendKeys(java.lang.CharSequence... keysToSend)
Sends keys to the active element. This differs from calling WebElement.sendKeys(CharSequence...) on the active element.
public class Demo_1 {
private WebDriver driver;
private Actions action;
private String baseUrl;
#Before
public void setUp() throws Exception {
File file = new File("C:\\Users\\ProgramFiles\\firefox.exe");
FirefoxProfile profile = new FirefoxProfile();
FirefoxBinary binary = new FirefoxBinary(file);
driver = new FirefoxDriver(binary, profile);
action = new Actions(driver);
baseUrl = "http://www.mortgagecalculator.org";
}
#Test
public void testUntitled() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.name("param[homevalue]")).click();
driver.findElement(By.name("param[homevalue]")).clear();
action.sendKeys("300000");
}
#After
public void tearDown() throws Exception {
//driver.quit();
}
}
I can do this alternatively, but in some cases when there is no WebElement, action.sendKeys can help to send CharSequence without any WebElement as parameter.
Can some come up with similar kind of issue, as the above code is not working :(
Cause its Actions class object so you need to tell the driver the actions you are performing.
action.sendKeys("300000").perform();
Will do the needful.