Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if the page has changed using Webdriver

Sometimes web pages' visible content depends on the page input elements state (for example, input element 'Choose your university' may appear only after you have chosen 'Student' in 'Job' field) or on clicking some page elements (like dropdown menu buttons). I am trying to automate the process of finding out such page elements dependencies using Selenium Webdriver. The first idea is to enter some stuff in text input fields, set checked/unchecked checkboxes, click some buttons/links, etc. and see if any elements on the page have appeared/disappeared. The problems are:

  • Is there an easy way to find out if something on the page has appeared? Well, I could make a map from web page elements to {'visible', 'invisible'} states after each change and find out if something has changed, but is there something built-in for this purpose?

  • Clicking some buttons might cause loading another page, and I want to stay in withing the page I am testing, is there a way to determine if click() method will cause loading another page and prevent it?

like image 679
karlicoss Avatar asked Aug 26 '12 09:08

karlicoss


People also ask

How to tell if a webpage has changed or not?

If the webpage has changed it prints "Changed", if not it prints "Not Changed". You can change these print statements to email you, or run whatever other python code you like.

How to check if a page is refreshed using Selenium WebDriver?

An element you interacting become stale when it is destroyed and recreated. Hence when page refreshes, every element in that page become stale. So we can check if the page is refreshed by waiting for an element in that page to become stale. The following Java code illustrate how it is achieved using Selenium webdriver.

How does this code detect changes in a webpage's content?

This code detects changes in a webpage's content by getting the initial HTML of a webpage and then repeatedly getting the HTML and checking it against the initial HTML every ten seconds. If the webpage has changed it prints "Changed", if not it prints "Not Changed".

How do I automate Microsoft Edge with WebDriver?

Automate Microsoft Edge (Chromium) with WebDriver To automate a browser using WebDriver, you must first start a WebDriver session using your preferred WebDriver testing framework. A session is a single running instance of a browser controlled using WebDriver commands. Start a WebDriver session to launch a new browser instance.


2 Answers

Divi's answer for question 2 is fine. For part 1 you can check if an element is displayed like you said:

 webElement.isDisplayed();

Or you could compare the html of the page before and after the event.

driver.getPageSource();

(You could possibly also check the url if that changes after each event).

The one problem with getting the source of the html is that an event might have triggered after your last action and not have completed, leaving the html the same. To get around this you could check some of the following conditions:

(Boolean) ((JavascriptExecutor)driver).executeScript("return jQuery.ready"); 
((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");

Or you might be using another javascript framework that has another function similar to jQuery.ready.

Finally you might have an issue with the event only triggering once you have changed the active element, tabbing out of the field etc. So you could run something like:

Actions actionObject = new Actions(driver); 
actionObject.sendKeys(Key.TAB).perform();

Or you could use javascript to set it(I haven't checked the below code and I would set the webElement to the html base element):

((JavascriptExecutor) driver).executeScript("arguments[0].focus();", webElement);

I don't suggest using webdriver to click on the body element as this might undo your last click.

I'm including Divi's answer for Question 2 for completeness:

We can check whether it is redirecting to another page or not by getting the url of the page and comparing it with expected url

WebDriver driver;

driver.getCurrentUrl() // will returns the String value

if your currrent url doesn't matches with your expected url means then you go for two ways

1) You can open your expected url again by using Open function in selenium (or) webdriver navigate method

driver.navigate().to("expected_url");

2) You can use back navigation

driver.navigate().back();
like image 79
James Avatar answered Sep 19 '22 22:09

James


Based on James' answer, and since our test site does not use jQuery, the following worked for me :

public static class WebDriverExtensions
{
    public static void WaitForPage(this IWebDriver driver)
    {
        WaitForPage(driver, 60, 200);
    }

    private static void WaitForPage(IWebDriver driver, int seconds, int waitFor)
    {
        while (!((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"))
        {
            System.Threading.Thread.Sleep(50);
        }
        bool stillChanging = true;
        int iterations = 0;
        int maxIterations = (1000 * seconds) / waitFor;
        string previous = "";
        string current = "";
        while (stillChanging && iterations < maxIterations)
        {
            current = driver.PageSource;
            System.Threading.Thread.Sleep(waitFor);
            stillChanging = (!previous.Equals(current));
            previous = current;
        }
    }

    public static void Click(this IWebElement el, IWebDriver driver)
    {
        el.Click();
        driver.WaitForPage();
    }
 }

What I do in my code, is call el.Click(driver) instead of el.Click(). The method will return after the page has stopped changing. You could also call the public driver.WaitForPage() method before/after changes that may change something on your page. The hard-coded values should be modified to ensure that your max timeout and period between checks for changes work as expected. Make the waitFor too small and you will not detect changes. Make it too big and you'll have to wait for a long time after each click.

like image 42
Christopher Akritidis Avatar answered Sep 22 '22 22:09

Christopher Akritidis