Address locator changes in responsive mode

In the previous section, we learned about running tests in responsive mode. Ekam makes it simple to bring up chrome to test applications in responsive mode.

Failing Test due to locator changes

Application’s controls (UI elements) could change, due to its responsive nature. Because of this change the test we authored fails in responsive mode.

When we execute the GoogleSearchTest - It fails as the “Google Search” button does not exist in responsive view.

Here is the code:

@Test(groups = "web")
public void shouldDoGoogleSearch() {

    String title = Page(GoogleHomePage.class)
            .search("testvagrant")
            .getTitle();

    assertEquals(title, "testvagrant - Google Search");

}
public class GoogleHomePage extends WebPage {

    protected By searchBox = queryByName("q");
    protected By searchButton = query("input[value='Google Search']");

    @WebStep(keyword = "When", description = "I hit search button")
    public GoogleHomePage search(String text) {

        textbox(searchBox).setText(text);
        element(searchButton).click();
        return this;
    }
    
    @WebStep(keyword = "And", description = "I return Title")
    public String getTitle() {

        return driver.getTitle();
    }
}

The test would fail with the below exception

java.lang.RuntimeException: Error waiting for element presence with selector: By.cssSelector: input[value='Google Search'].
	at com.testvagrant.ekam.atoms.web.Element.waitUntilPresent(Element.java:118)

Solution

Multi Platform Finder : Ekam provides multi platform finder - which helps you to declare locators for normal and responsive mode in a single statement.

    private MultiPlatformFinder searchButton =
            finder(query("input[value='Google Search']"), query("ul[role='listbox']>li"));

The two locators are corrosponding to:

  1. Locator of search button in Normal view
  2. Locator of search button in Responsive view as shown in below image

Refactor By statement of searchButton locator to use Multi Platform Finder

public class GoogleHomePage extends WebPage {

    private MultiPlatformFinder searchButton =
            finder(query("input[value='Google Search']"), query("ul[role='listbox']>li"));
    private By searchBox = queryByName("q");

    @WebStep(keyword = "When", description = "I hit search button")
    public GoogleHomePage search(String text) {

        textbox(searchBox).setText(text);
        element(searchButton).click();
        return this;
    }
        
    @WebStep(keyword = "And", description = "I return Title")
    public String getTitle() {

        return driver.getTitle();
    }
}

Web Feed

Create a web feed file responsive.webfeed to specify the mobileEmulation as shown below.

{
  "desiredCapabilities": {
  },
  "arguments": [
  ],
  "preferences": {
  },
  "extensions": [
  ],
  "experimentalOptions": {
    "mobileEmulation": {
      "deviceName" : "iPhone 7"
    }
  }
}

Config

Create a new configurtion file as responsive.properties and add properties as shown below.

# Web Config

# Target Browser. Supported values <any | chrome | firefox | msedge | responsive>
web.target: responsive

# Feed file having desiredCapabilities, arguments etc
web.feed: responsive.webfeed

Execute test from IDE

Hurray !! A single GoogleSearchTest - can now execute in both responsive and normal mode.

In absence of Ekam, this was handled by

Creating a repo for desktop browser and another repo for responsive

or Authoring two different tests - one for desktop browser and one for responsive

With Ekam, now you can author test once and execute twice !!