Monday, January 30, 2023

Portability testing a web application UI with Selenium

Portability testing of web application UI can easily be handled with Selenium. To handle cross browser testing you can implement a driver instantiation pattern like the one shown below,


public class TestBase {
protected static WebDriver driver;
public static void instantiateDriver() {
if (BROWSER.equals("chrome")) {
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
driver = new ChromeDriver(options);
} else if (BROWSER.equals("edge")) {
WebDriverManager.edgedriver().setup();
EdgeOptions options = new EdgeOptions();
options.addArguments("start-maximized");
driver = new EdgeDriver(options);
} else{
Logger.getAnonymousLogger().log(Level.INFO,"An unsupported browser argument was provided at run-time.");
}
}
}
view raw TestBase.java hosted with ❤ by GitHub


For cross mobile agent testing, you can use a TestNG data provider to pass in the device types into your test method and repeat the test for as many emulated devices as you would like.

Find the complete project here, https://github.com/handakumbura/SeleniumAutomationEmployerProfile/tree/feature/cross_browser_cross_agent


public class CrossMobileAgentTest extends TestBase {
@AfterMethod
public static void cleanUp() {
driver.quit();
}
@Test(dataProvider = "userAgentsData")
public static void testDataProvider(String s) {
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("mobileEmulation", Map.of("deviceName", s));
driver = new ChromeDriver(options);
driver.get(Constants.DROPDOWN_PAGE_URL);
DropDownPageFunctions dropDownPageFunctions = new DropDownPageFunctions(driver);
TestData testData = JSONUtil.readTestData("002");
dropDownPageFunctions.selectValueFromDropDown(testData.getStringValue());
//Asserts to see if the dropdown selection has been set.
Assert.assertTrue(dropDownPageFunctions.isTheGivenValueSelected(testData.getStringValue()), "The given value was not set as the dropdown selection.");
}
@DataProvider(name = "userAgentsData")
public static Object[][] generateData() {
return new String[][]{{"iPhone 5"}, {"iPhone 6"}, {"Nexus 6"}};
}
}








Saturday, January 14, 2023

How to read the user selection from a radio button group using Selenium?

SeleniumUtil library has been occupying my free time for the past couple of months. Since I’ve already written at length about what it is I won’t do that again here but if you really want to know you look here [1] [2].

When I implemented the abstraction wrapper for the HTML radio button group I ran into a problem. How would someone go about reading the user selection form a radio button group? Take a look at this HTML block,



According to the HTML5 spec, Radio Buttons belonging to the same group would have the same name attribute value. So toggling a given radio button using Selenium is not too difficult, but unlike Checkbox's the Radio Buttons I've seen in the wild (including this W3C example) doesn't append a checked attribute upon user selection. This complicates things.

I first tried retrieving the selection using the $0 variable that stores the user selection. But it turned out it was a browser specific variable that is not exposed to JavaScript. So how can we get a handle on this element and read its value? I did this,

// store the value of the radio button that the user selects by attaching event handlers to the radio group members.
window.radio; document.querySelectorAll('[name="age"]').forEach(elem => {elem.addEventListener('click',function(e){ window.radio = e.target.defaultValue})});
// read the stored value later when the user has made the selection.
return window.radio;

But you can save all the pain because this snippet and bunch of other JavaScript goodies are available in SeleniumUtil 0.7.5.  

Saturday, January 7, 2023

SeleniumUtil 0.7.0 is now available with a few Java Script utility methods

Abstraction helps to promote code reuse and reduce development time among other benefits. When considering Selenium based test automation, you can abstract at many different points such as at dependency, infrastructure, technology, page, component or even at the element or locator level. SeleniumUtil is an open source library that aims to provide generic abstractions and other useful utilities so that you don’t need to worry about them in your Selenium based test automation projects.

Version 0.7.0 is now available in maven central and it provides a few technology level abstractions in the form of a few parameterized Java Script methods.


Usage


package com.dumiduh.other;
import com.dumiduh.constants.Constants;
import com.dumiduh.utils.TestBase;
import io.github.handakumbura.EventListener;
import io.github.handakumbura.JavaScriptHelper;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class JavaScriptHelper extends TestBase {
private static final String OPTIONS_BLOCK = "'<option>papaya</option><option>apple</option>'";
private static final String DROPDOWN_CSS_SELECTOR = "#dropdown";
private static final String CALLBACK = "function(){console.log('clicked')}";
@BeforeClass
public static void setup() {
instantiateDriver();
driver.get(Constants.DROPDOWN_PAGE_URL);
}
@Test
public static void dropDownTest() {
JavaScriptHelper javaScriptHelper = new JavaScriptHelper(driver);
//pauses execution up to 2 minutes.
javaScriptHelper.pauseTheDOMForAGivenDuration(5000);
//attaches a valid and well-formed HTML block as a child of a given element.
javaScriptHelper.appendHTMLBlockAsAChild(OPTIONS_BLOCK,DROPDOWN_CSS_SELECTOR);
//attaches a callback function to a given event in the DOM.
javaScriptHelper.attachASnippetAsAEventCallBack(DROPDOWN_CSS_SELECTOR, EventListener.CLICK,CALLBACK);
}
@AfterClass
public static void cleanUp() {
driver.quit();
}
}









What's in my Bag? EDC of a Tester