I'm trying to get page content which is dynamically loaded after you get to the end of the page but after use sendKeys(Keys.END) page content seems to be the same.
Any chance to handle it and get new reloaded source? I'm using PhantomJS in Java.
The basic idea is to explicitly wait for a presence or visibility of an element loaded dynamically - then, call the getPageSource() method.
For example, if there is a div with a "additionalContent" class dynamically loaded, here is how you can wait for it to appear:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.additionalContent")));
// get the page source
System.out.println(driver.getPageSource());
Related
I am navigating from one page to another. They both use the same templates the only difference is the text contained within the .image-header__title class.
I want to select the link to navigate to the other page and assert that is has arrived at the right page by using .gettext() as below:
#Test
public void When_I_Click_patterns_page_is_returned() {
driver.get("https://test.co.uk/fabric-range/");
String actualString = fp.ClickPattern().getText();
assertTrue(actualString.contains("Semi-plain Fabrics"));
}
public WebElement ClickPattern() {
driver.findElement(By.cssSelector(".image-blocks .image-blocks__items .image-blocks__item:nth-child(7) a")).sendKeys(Keys.ENTER);
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(20, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement fabricType = wait.until(driver -> driver.findElement(By.cssSelector(".image-header__inner .image-header__content .image-header__title")));
return fabricType;
}
I am waiting for the .image-header__title to be present, however as this element is on the initial landing page, the getText() method is not returning the text from the second page but from the first.
Is there anyway I can wait for the second page to be loaded before performing the getText() method?
Do you know if you application reloads the page on "sendKeys(Keys.ENTER)" or does it simply re-render the HTML? Further more, even if it does reload the page, are post load events used to generate the HTML via javascript?
Selenium will only block while a page is loading, so if "sendKeys(Keys.ENTER)" triggers javascript to re-render the HTML, then it will not wait for that process to finish, and instead return straight away, and as a result exhibit the behavior you see.
Purely for debugging purposes (!!!!!) have you tried adding a sleep of a few seconds between "sendKeys(Keys.ENTER)" and the "Webdriver wait"? Assuming that this does result in the updated text being returned, then this confirms that your application is not reloading and simply re-rendering HTML.
Is there another such as a page loading indicator that your test could hook into instead? If there was, your "wait until" would be looping until the loading indicator is NOT displayed. Once this had exited, you can continue knowing that your page is ready to be interacted with.
Yes, use ExpectedConditions#stalenessOf.
Grab a reference to an element on Page 1, e
Trigger the action that changes pages
Wait for e to go stale
Continue the script on Page 2
public WebElement ClickPattern() {
WebElement e = driver.findElement(By.cssSelector(".image-blocks .image-blocks__items .image-blocks__item:nth-child(7) a"));
e.sendKeys(Keys.ENTER);
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.stalenessOf(e));
return wait.until(ExpectedCondition.visibilityOfElementLocated(By.cssSelector(".image-header__inner .image-header__content .image-header__title")));
}
I don't think you need the second wait... but you might so I left it in.
Locator for this is correct, but when running it in Selenium Webdriver, I am getting the same error .
I have used different kinds of waits like Implicit wait, Explicit wait, and Wait for Presence of element
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#id = 'bs-example-navbar-collapse-1']/ul[2]/li[1]")));
driver.findElement(By.xpath("//div[#id = 'bs-example-navbar-collapse-1']/ul[2]/li[1]")).click();
Instead of using 'presenceOfElementLocated(By locator)', use 'visibilityOfElementLocated(By locator)'.
'presenceOfElementLocated(By locator)' only confirms the presence of element in DOM, it does not mean that element is visible or enable. But if you use 'visibilityOfElementLocated(By locator)', then it confirms the element is present in DOM as well as visible. If you are clicking the element you can also use 'elementToBeClickable(By locator)';
Its Shine.com , clicking on Login Link at top right hand side
You should try using By.linkText() to click on Login button as below :-
driver.get("http://www.shine.com/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Login"))).click();
This question already has answers here:
Wait for page load in Selenium
(48 answers)
Closed 6 years ago.
I am trying to automate some test cases using Java and Selenium WebDriver. I have the following scenario:
There is a page named 'Products'. When I click on 'View Details' link
in the 'Product' page, a popup (modal-dialog) containing the details of the item appears.
When I click on the 'Close' button in the popup the popup closes and
the page automatically refreshes (the page is just reloading, the contents remain unchanged).
After closing the popup I need to click on 'Add Item' button in the
same page. But when WebDriver trying to find the 'Add Item' button,
if the internet speed is too fast, WebDriver can find and click the
element.
But if the internet is slow, WebDriver finds the button before the
page refresh, but as soon as the WebDriver click on the button, the page refreshes and StaleElementReferenceException occurs.
Even if different waits are used, all the wait conditions become true
(since the contents in the page are same before and after reload)
even before the page is reloaded and StaleElementReferenceException
occurs.
The test case works fine if Thread.sleep(3000); is used before clicking on the 'Add Item' button. Is there any other workaround for this problem?
3 answers, which you can combine:
Set implicit wait immediately after creating the web driver instance:
_ = driver.Manage().Timeouts().ImplicitWait;
This will try to wait until the page is fully loaded on every page navigation or page reload.
After page navigation, call JavaScript return document.readyState until "complete" is returned. The web driver instance can serve as JavaScript executor. Sample code:
C#
new WebDriverWait(driver, MyDefaultTimeout).Until(
d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
Java
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
Check if the URL matches the pattern you expect.
It seems that you need to wait for the page to be reloaded before clicking on the "Add" button.
In this case you could wait for the "Add Item" element to become stale before clicking on the reloaded element:
WebDriverWait wait = new WebDriverWait(driver, 20);
By addItem = By.xpath("//input[.='Add Item']");
// get the "Add Item" element
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(addItem));
//trigger the reaload of the page
driver.findElement(By.id("...")).click();
// wait the element "Add Item" to become stale
wait.until(ExpectedConditions.stalenessOf(element));
// click on "Add Item" once the page is reloaded
wait.until(ExpectedConditions.presenceOfElementLocated(addItem)).click();
You can do this in many ways before clicking on add items:
WebDriverWait wait = new WebDriverWait(driver, 40);
wait.until(ExpectedConditions.elementToBeClickable(By.id("urelementid"))); // instead of id you can use cssSelector or xpath of your element.
or:
wait.until(ExpectedConditions.visibilityOfElementLocated("urelement"));
You can also wait like this. If you want to wait until invisible of previous page element:
wait.until(ExpectedConditions.invisibilityOfElementLocated("urelement"));
Here is the link where you can find all the Selenium WebDriver APIs that can be used for wait and its documentation.
yes stale element error is thrown when (taking your scenario) you have defined locator strategy to click on 'Add Item' first and then when you close the pop up the page gets refreshed hence the reference defined for 'Add Item' is lost in the memory so to overcome this you have to redefine the locator strategy for 'Add Item' again
understand it with a dummy code
// clicking on view details
driver.findElement(By.id("")).click();
// closing the pop up
driver.findElement(By.id("")).click();
// and when you try to click on Add Item
driver.findElement(By.id("")).click();
// you get stale element exception as reference to add item is lost
// so to overcome this you have to re identify the locator strategy for add item
// Please note : this is one of the way to overcome stale element exception
// Step 1 please add a universal wait in your script like below
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); // just after you have initiated browser
There are two different ways to use delay in selenium one which is most commonly in use. Please try this:
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
second one which you can use that is simply try catch method by using that method
you can get your desire result.if you want example code feel free to contact me defiantly I will provide related code
I have successfully saved the source code of a webpage but some webpages dynamically serve the info. That makes it so I cannot get the info that’s on the page.. If I right click and "inspect element" it’s there.. Is there any way to copy what is loaded from that webpage and save it to a text file?
if you're looking for the web page source use this
Create a driver instance
WebDriver driver=new WebDriver();
call the below function when you think the dynamically served content is appeared on the web page
driver.getPageSource();
this should work.
use selenium webdriver to get page source and even you can get the values of a particular element say inputbox, checkbox,dropdown etc from the webpage. Also you can enter the values and submit the form
reate a new instance of the html unit driver
// Notice that the remainder of the code relies on the interface,
// not the implementation.
WebDriver driver = new HtmlUnitDriver();
// And now use this to visit Google
driver.get("http://www.google.com");
System.out.println( driver.getPageSource());
driver.quit();
}
}
refer getPageSource() in Selenium WebDriver(a.k.a Selenium2) using Java
https://code.google.com/p/selenium/wiki/GettingStarted
I'm trying to use Selenium (Java) to automate some searches.
When I go to the page and click Inspect Element on the search bar, I see that it has the id searchBox and name q, both of which are potentially useful. Nevertheless, these properties are nowhere to be found in the HTML when I go to View Source.
When I try to use
WebElement search = driver.findElement(By.id("searchBox"));
or
WebElement search = driver.findElement(By.name("q"));
both come back as unable to be found.
How do I proceed with populating the search field then hitting submit (the submit button also is missing in the source page) if I can't find either of these elements?
EDIT:
As requested, here's a more detailed picture of what's wrong:
The URL of the page accessed by WebDriver is http://www.ycharts.com using the line
driver.get("http://www.ycharts.com/login");
If you go to this page with your actual web browser, right click on the search bar and choose Inspect Element, you'll see that its ID is "searchBox" and its name is "q". However, if you go to view the same page's source, you'll see that there's no such element in the HTML. Clearly, this is why WebDriver can't find it.
driver was initiated as follows:
WebDriver driver = new HtmlUnitDriver();
When I try something like
WebElement search = driver.findElement(By.id("searchBox"));`
The exception returned is:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element with ID: searchBox
So, back to the original question: clearly, the element is there, but it's not in the HTML – how do you interact with it?
The problem is being caused by the fact that the search box is added to the html post page load by javascript.
The HTML returned by http://ycharts.com/ does not contain the searchbox, therefore when Selenium thinks the page has finished loading (i.e DOM ready state), there is no search box.
In order to interact with the search box, you need to tell Selenium to wait until the box appears in the DOM.
The easiest way to achieve this is with WebDriverWait;
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));