Selenium RC : Page is not loading compeletelly - selenium

When I run my selenium rc script page is not loading completely because of change in the urls.
Earlier it was working fine when url was something link this
https://testersworld.com/
But now it changed to (updated the URL in the script before run)
https://testersworld.com/#login
Because of which when I run the script browser launches with specified url but fails to displayed login popup.
How to handle this https://testersworld.com/#login which gives login pop after page load. I used all methods of wait.

try this:
driver.manage().deleteAllCookies();
driver.get("https://testersworld.com/");
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
or
driver.manage().deleteAllCookies();
driver.get("https://testersworld.com/");
Thread.sleep(1000);
or
select locator on login page (e.g. input login(e-mail ) field):
String cssLocator=..blablabla...;
and use fluentWait mechanism:
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo; } ;
fluentWait(By.cssSelector(cssLocator));

Related

How to interact with webelement on popup while browser loader running?

I have an authentication popup before loading the website and while popup display on the webpage and a loader display running on the browser it means webpage not loaded completely.
And as per selenium if complete webpage not loaded initially, selenium not interact with elements
Need help on this.
Use following method with Java + Selenium :
public boolean isPageReady(WebDriver driver){
boolean readyStateComplete = false;
while (!readyStateComplete){
JavascriptExecutor executor = (JavascriptExecutor) driver;
readyStateComplete = executor.executeScript("return document.readyState") == "complete";
}
return readyStateComplete;
}
For C# + Selenium :
private void WaitUntilDocumentIsReady(TimeSpan timeout){
var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
var wait = new WebDriverWait(WebDriver, timeout);
// Check if document is ready
Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
.ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
wait.Until(readyCondition);
}
You can wait until the page is completely loaded via JavaScript.
private void WaitUntilLoaded()
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until((x) =>
{
return ((IJavaScriptExecutor)this.driver)
.ExecuteScript("return document.readyState").Equals("complete");
});
}
Another option is to wait for a specific element(s) to be visible on the page
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(
By.XPath("some Xpath")));
Source here: https://www.automatetheplanet.com/advanced-webdriver-tips-tricks-part-1/

Wait to perform two actions - selenium/ java

I'm trying to use Fluent wait to perform two actions as below:
Click on search button
Check the result for the element
Right now I'm trying with the below code and it doesn't seem to work:
public SendMailPage waitForSometime() throws Exception {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofMinutes(2))
.pollingEvery(Duration.ofSeconds(10))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
driver.findElement(By.xpath("//BUTTON[#type='submit'][text()='Search']")).click();
driver.findElement(By.xpath("xpath of the element i'm waiting to find"));
return driver.findElement(By.xpath("xpath of the element i'm waiting to find"));
}
});
element.isDisplayed();
return new SendMailPage();
}
Can someone guide me on how to fix this?
***UPDATED CODE: where waiting for a single element also doesn't work :
public SendMailPage assertMailSubject() throws Exception {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofMinutes(2))
.pollingEvery(Duration.ofSeconds(30))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("the element that i am waiting for"));
}
}
);
return new SendMailPage();
}
I fixed both the problems:
The code was not working as the NoSuchElementException was from Java util instead of Selenium.
And for performing two actions, I just added by Search key action before the return statement.

Selenium xpath getting changed during run time

Scenario - Valid login to www.homeshop18.com and then from the Digital Menu select "Samsung".
The results are displayed and now I need to choose another brand - Micromax from the Brand section (displayed at the left side of the page)
which requires scrolling and selecting Micromax.
Issue:
Though the xpath of Micromax is correct which is //*[#id='filter_1Option_12']//div[#class='ez-checkbox'] but I see during run time of the script - some other brand is getting selected instead of micromax.
Kindly advise.
//Class for valid login to www.homeshop18.com
public class HomeShop_Login_Test
{
#FindBy(xpath="//a[#id='signInHeaderLink']") WebElement SignIn_Link;
#FindBy(xpath=".//input[#id='emailId']") WebElement Email;
#FindBy(xpath=".//input[#id='existing_user_radio']") WebElement Existing_User_Radio;
#FindBy(xpath=".//input[#id='new_user_radio']") WebElement New_User_Radio;
#FindBy(xpath=".//input[#id='password']") WebElement Password;
#FindBy(xpath=".//a[#id='signin']") WebElement SignIn_Button;
#FindBy(xpath="//a[#title='Close']") WebElement Close_Home;
public void Login_Valid()
{
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement SignIn_Link = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[#id='signInHeaderLink']")));
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("arguments[0].click()", SignIn_Link);
Email.sendKeys("xxx#gmail.com");
boolean selected;
selected = New_User_Radio.isSelected();
if(selected)
{
Existing_User_Radio.click();
}
Password.sendKeys("xxx");
SignIn_Button.click();
}
//Class to choose Samsung from Digital menu
public class Browse_Samsung_Mobile
{
#FindBy(xpath="//*[#id='CategoryMenu1']//a[text()='Digital']") WebElement Digital_Menu;
#FindBy(xpath="//*[#id='CategoryMenu1']//a[#title='Samsung']") WebElement Samsung_SubMenu;
#FindBy(xpath="//*[#id='filter_1Option_19']//span[#class='selected_filter_img']") WebElement Micromax;
public void Browse_Samsung()
{
WebDriverWait wait = new WebDriverWait(driver, 30);
Actions act = new Actions(driver);
act.moveToElement(Digital_Menu).perform();
act.click(wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='CategoryMenu1']//a[#title='Samsung']")))).build().perform();
//WebElement Micromax = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#id='filter_1Option_12']//span[#class='selected_filter_img']")));
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("arguments[0].click()", Micromax);
}
}
//class to call above two classes
public class Validate_Browse_Samsung_Mobile
{
WebDriver driver;
#Test
public void Validate_Browse()
{
driver = BrowserFactory.getBrowser("Firefox");
driver.get(DataProviderFactory.getConfig().getURL());
HomeShop_Login_Test login = PageFactory.initElements(driver, HomeShop_Login_Test.class);
login.Login_Valid();
Browse_Samsung_Mobile browse = PageFactory.initElements(driver, Browse_Samsung_Mobile.class);
browse.Browse_Samsung();
}
}
You should try with their name using title attribute as below :-
WebElement micromax = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("a[title ~= "Micromax"] input")));
You should use following XPath to choose proper check-box:
//a[#title="GSM Mobile Phones - Micromax"]/div/input

How to write a generalized web driver wait in Selenium

I am trying to write a generalized web driver wait to wait for elements to be clickable. But I found out online of Web Driver waits that are written specific to By.id or By.name.
Suppose Below are two WebElements
public WebElement accountNew() {
WebElement accountNew = driver.findElement(By.xpath("//input[#title='New']"));
waitForElementtobeClickable(accountNew);
return accountNew;
}
public WebElement accountName() {
WebElement accountName = driver.findElement(By.id("acc2"));
waitForElementtobeClickable(accountName);
return accountName;
}
Below is the generalized waitofrelementtobeclickable.
public static void waitForElementtobeClickable(WebElement element) {
try {
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(element));
System.out.println("Got the element to be clickable within 10 seconds" + element);
} catch (Exception e) {
WebDriverWait wait1 = new WebDriverWait(driver, 20);
wait1.until(ExpectedConditions.elementToBeClickable(element));
System.out.println("Got the element to be clickable within 20 seconds" + element);
e.printStackTrace();
}
}
but it doesn't seem to work. Any suggestions on how only one generalized code can be written for either xpath, or id, or class or Css can be written?
The problem is not in your function, its in your driver.findElement as you try to locate the element before it exist in the DOM. You can use implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
This will wait up for 10 seconds for any element to exist in the DOM before when locating it.
Or locate your element using explicit wait
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[#title='New']")));
This will wait up to 10 seconds for your element to be visible.
You can (and should) use both of course.
You can change your code to something like that
public static WebElement waitForElementtobeClickable(By by) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(by));
System.out.println("Got the element to be clickable within 10 seconds" + element);
return element;
}
public WebElement accountNew() {
WebElement accountNew = waitForElementtobeClickable(By.xpath("//input[#title='New']"));
return accountNew;
}
You send your By locator to waitForElementtobeClickable and use elementToBeClickable(By) instead of elementToBeClickable(WebElement), so you can use xpath, id, class etc.

Keep on refreshing the page until certain element to appear?

I have a scenario like, i want to keep on refreshing the page until some element to appear in the page. Can anyone please help me on the same?
I am using the below code for the same but the page is not refreshing after five second
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
Thanks
Sudhansu
Try using the FluentWait class.
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
In that way Selenium will just wait for a certain period of time until certain elements have been loaded.
I hope that will solve your problem so you don't have to refresh the page.
Edited:
As MrTi so friendly points out, the above code will not refresh your page. It will only wait for a certain period of time until certain elements have been loaded. I just thought it might solve the problem, without you having to refresh the page. If that does not solve your problem and you still need to refresh your page, then you need to add driver.navigate().refresh() before the return, like this:
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
driver.navigate().refresh()
return driver.findElement(By.id("foo"));
}
});
Thank you EmilC for your proposal.
It's also posible to declare the Function using java lambda's syntax the following way.
Wait<WebDriver> wait = new FluentWait<WebDriver>(ctx.driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
wait.until((webDriver) -> {
webDriver.navigate().refresh();
return driver.findElement(by);
});
if $all_loaded = true > do something > else > refresh page