0

I'm using selenium 4 and trying to locate some elements (Username and password credentials) "Username : Admin Password : admin123" using Relative Locators selenium 4 new feature but the Code throws org.openqa.selenium.NoSuchElementException: Cannot locate an element using [unknown locator] but when I debugged the code to test it, it passed successfully ,found the elements and printed the values on the console. anyone has a proposed solution?

org.openqa.selenium.NoSuchElementException: Cannot locate an element using \[unknown locator\]
For documentation on this error, please visit: https://selenium.dev/exceptions/#no_such_element
Build info: version: '4.4.0', revision: 'e5c75ed026a'
System info: host: 'DESKTOP-M0R33E6', ip: '192.168.1.4', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '13.0.2'
Driver info: driver.version: RemoteWebDriver

    at org.openqa.selenium.By.findElement(By.java:124)
    at org.openqa.selenium.remote.ElementLocation$ElementFinder$1.findElement(ElementLocation.java:136)
    at org.openqa.selenium.remote.ElementLocation.findElement(ElementLocation.java:80)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:365)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:357)
    at OrangeHrm.Pages.LoginPage.getUsernameUsingRelativeLocator(LoginPage.java:29)
    at OrangeHrm_Tests.Login.LoginTests.test_GetUserCredentials(LoginTests.java:10)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1507)
    at org.testng.TestRunner.privateRun(TestRunner.java:808)
    at org.testng.TestRunner.run(TestRunner.java:603)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
    at org.testng.SuiteRunner.run(SuiteRunner.java:326)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
    at org.testng.TestNG.runSuites(TestNG.java:1092)
    at org.testng.TestNG.run(TestNG.java:1060)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)

Website URL: https://opensource-demo.orangehrmlive.com/web/index.php/auth/login

LoginPage.java

package OrangeHrm.Pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.locators.RelativeLocator;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;


public class LoginPage {

    private WebDriver driver;
    private By loginPageTitle = By.tagName("h5");
    WebElement usernameCredential;
    WebElement passwordCredential;

    public LoginPage(WebDriver driver){
        this.driver = driver;
    }

    public String getUsernameUsingRelativeLocator(){
        usernameCredential = driver.findElement(RelativeLocator.with(By.xpath("//div[contains(@class , 'oxd-sheet--rounded')]/p[1]"))
                .below(loginPageTitle));
        System.out.println(usernameCredential.getText());
        return  usernameCredential.getText();
    }

    public String getPasswordUsingRelativeLocator(){

        passwordCredential = driver.findElement(RelativeLocator.with(By.xpath("//div[contains(@class , 'oxd-sheet--rounded')]/p[2]"))
               .below(username));
        System.out.println(passwordCredential.getText());
        return  passwordCredential.getText();
    }
}

OrangeHrmWebTestBase.java

package OrangeHrm_Tests.Base;

import OrangeHrm.Pages.LoginPage;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.time.Duration;

public class OrangeHrmWebTestBase {

    private WebDriver driver;
    protected LoginPage loginPageObj;

    @BeforeClass
    public void setUp(){
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");
        loginPageObj = new LoginPage(driver);

    }

    @AfterClass
    public void teatDown(){
        driver.quit();
    }
}

LoginTests.java

package OrangeHrm_Tests.Login;

import OrangeHrm_Tests.Base.OrangeHrmWebTestBase;
import org.testng.annotations.Test;

public class LoginTests extends OrangeHrmWebTestBase {

    @Test
    public void test_GetUserCredentials(){
        loginPageObj.getUsernameUsingRelativeLocator();
        loginPageObj.getPasswordUsingRelativeLocator();
    }
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • might need another ) maybe: driver.findElement(RelativeLocator.with(By.xpath("//div[contains(@class , 'oxd-sheet--rounded')]/p[1]")).below(loginPageTitle))); Probably easier to create the By... so By locator = RelativeLocator.with(By.xpath("//div[contains(@class , 'oxd-sheet--rounded')]/p[1]")).below(loginPageTitle)); And then use that in findElement. – pcalkins Jan 17 '23 at 19:16
  • Tried but the same error is still reproduced. – Ali Eleish Jan 17 '23 at 19:31
  • not real sure if these are supported by the drivers... (I've never used them myself...) You can always create an XPATH to do essentially the same thing... it's just relative to the DOM structure instead of view. (using things like parent, child, etc...) The W3C webdriver standard doesn't mention anything about these relative locators: https://www.w3.org/TR/webdriver/#locator-strategies – pcalkins Jan 17 '23 at 20:18

1 Answers1

1

You seem to be pretty close using Below as a Relative Locator within the OrangeHRM website.

However instead of using the <div> with the text Username : Admin and Password : admin123 as Relative Locators you can use the <label> with text as Username and Password.

Code Block:

package AwesomeDay;

import java.time.Duration;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.locators.RelativeLocator;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RelativeLocators2 {

    public static void main(String[] args) {

        System.setProperty("webdriver.chrome.driver", "C:\\BrowserDrivers\\chromedriver.exe");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");
        WebDriver driver = new ChromeDriver(options);
        driver.get("https://opensource-demo.orangehrmlive.com/web/index.php/auth/login");

        //WebElement userNameLabel =  driver.findElement(By.xpath("//label[text()='Username']"));
        WebElement userNameLabel = new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[text()='Username']")));
        By userName = RelativeLocator.with(By.tagName("input")).below(userNameLabel);
        driver.findElement(userName).sendKeys("Ali");

        WebElement passwordLabel =  driver.findElement(By.xpath("//label[text()='Password']")); 
        By password = RelativeLocator.with(By.tagName("input")).below(passwordLabel);
        driver.findElement(password).sendKeys("Eleish");
    }
}
        

Browser Snapshot:

Relative_Java

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Great to know these are supported. Is it only chromedriver that supports these? Also, is there a significant speed difference vs. using XPATH? Seems like the browser would have to get all the bounding rectangles in the current DOM? – pcalkins Jan 17 '23 at 20:48
  • @pcalkins Yeap, the browser would have to get all the bounding rectangles of the referenced element in the current DOM. – undetected Selenium Jan 17 '23 at 20:50