Selenium self-healing
How to self-heal Selenium locators
testRigor has a library for Selenium Java TestNG/JUnit that would automatically heal the locators in selenium.
Let’s consider two versions of the application under test. The first one and the second one.
As you can see, they work identically. However, the rendering of the “Update Message” button changed from
to
How to use it
SelfHealingDriver driver = TestRigor.selfHeal(new ChromeDriver(), "a2518f3a-3e8b-484a-befe-23b9160ef166");
package com.yourcompany; import static org.assertj.core.api.Assertions.assertThat; import com.testrigor.selfhealingselenium.SelfHealingDriver; import com.testrigor.selfhealingselenium.TestRigor; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.remote.RemoteWebDriver; import org.testng.annotations.Test; @Test public class SelfHealingIT { private static final int SECONDS_TIMEOUT = 4; private static final String TEST_TEXT = "test123"; public void test_Selenium_tests_heals_for_path_and_tag_change() { System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver"); //RemoteWebDriver driver = new ChromeDriver(); SelfHealingDriver driver = TestRigor.selfHeal(new ChromeDriver(), "a2518f3a-3e8b-484a-befe-23b9160ef166"); driver.manage().timeouts().implicitlyWait(SECONDS_TIMEOUT, TimeUnit.SECONDS); driver.get("http://r4d4.info/form-button-label"); actualTest(driver); driver.get("http://r4d4.info/form-button-label2"); actualTest(driver); } private void actualTest(RemoteWebDriver driver) { WebElement input = driver.findElementById("messageNew"); WebElement button = driver.findElementById("changer"); input.sendKeys(TEST_TEXT); button.click(); WebElement result = driver.findElementByXPath("/html/body/div/p[1]"); String text = result.getText(); assertThat(text).contains(TEST_TEXT); } }
In this example above, it will auto-heal the changer
id, which is changed in the next version of the page.
How does it work?
- When your test is executed successfully, testRigor will get your locators and pages on which these locators were used and will infer user intent for each locator. For instance, in the example above, it will record and store user-level intent
click "Update Message"
as the intent behind the click. - When locator finding will fail in your code, it will use stored user-level intent and the page to find the new locator for the intended element. If found, it will use the new one. If not found – it will fail.
Would it lead to false positives?
Not at all. Since testRigor will infer the user-level intent, your test will succeed when and only when the intended action is possible from end-user’s perspective. For example, when testRigor can find the button with the same name (if there was only one button with this name previously). If the button is renamed AND your code won’t be able to find it by locator – testRigor will fail to avoid the false-positives.
You can think as if testRigor converts your tests into manual tests and if the test can’t be executed manually successfully – testRigor will fail.
Save your time on test maintenance
- Investigation of why the test failed. It will log out the end-user-level steps as you go through the test.
- Figuring out what is the new locator to replace the one that no longer works.
To get early access to this feature, request a demo and mention Selenium plugin and code FIRST10
to be included to the list of first 10 companies with early access.
How start using it today
<dependency> <groupId>com.testrigor <artifactId>self-healing-selenium-3 <version>0.1.1-SNAPSHOT </dependency>
<dependency> <groupId>com.testrigor <artifactId>self-healing-selenium-4 <version>0.1.1-SNAPSHOT </dependency>
<repositories> <repository> <id>ossrh <url>https://s01.oss.sonatype.org/content/repositories/snapshots </repository> </repositories>
How to use
@Test public void input_contains_value() { RemoteWebDriver driver = new ChromeDriver(); driver.get("some page"); WebElement element = driver.findElement(By.id("firstNameInput")); assertThat(element.getText()).contains("John"); }
@Test public void input_contains_value() { RemoteWebDriver driver = new ChromeDriver(); SelfHealingDriver selfHealingDriver = TestRigor.selfHeal(driver, "API_TOKEN"); selfHealingDriver.setTestCaseName("test"); //This needs to be configure for each @Test driver.get("some page"); WebElement element = selfHealingDriver.findElement(By.id("firstNameInput")); assertThat(element.getText()).contains("John"); }
setTestCaseName(String testCaseName);
on each @Test
annotated method, this is for creating a relationship between the locators and the test.
Thank you for your request. Please select date and time for a demo.