0

I have tests that passing by if i run it none headless and if headless mode are on which is running my tests under the boot then some tests are failing with an exception that element cannot be located. What to do in such scenarios

Also does it matter how big is a window size at all? currently i have the following, but i guess if they passing wish such window size none headless why would some fail headless

@BeforeEach
public void setUp() {
    WebDriverManager.chromedriver().setup();
    driver = new ChromeDriver(new ChromeOptions()
            .addArguments("start-maximized")
            .addArguments("--disable-popup-blocking")
            .addArguments("--headless"));
    driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    loginToEnvironment();
}

In headless mode some element is not located

Elements initialisation done by PageFactory.init

public class BasePage {

    public WebDriver driver;
    protected Wait wait;

    public BasePage(WebDriver driver) {
        initializePage(driver);
        this.wait = new Wait(driver);
    }

    final protected void initializePage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(new AjaxElementLocatorFactory(driver, 20), this);
    }
}

enter image description here

SignUp test

@Test
    public void shouldSignUpSuccessfully() {
        signUpModal.signUp((SignUp) credentials)
                .getCountryModalInstance()
                .chooseCountry(((SignUp) credentials).getCountry())
                .clickOnSaveButton();
        assertTrue(homePage.getMyAccountName().getText().isEmpty());
    }

Stack track trace:

Timed out after 20 seconds. Unable to locate the element
org.openqa.selenium.NoSuchElementException: Timed out after 20 seconds. Unable to locate the element
    at org.openqa.selenium.support.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:99)
    at org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler.invoke(LocatingElementHandler.java:38)
    at com.sun.proxy.$Proxy17.getText(Unknown Source)
    at com.opngo.nowos.selenium.SignUpServiceTest.shouldSignUpSuccessfully(SignUpServiceTest.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:171)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:115)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:171)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:115)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:171)
    at java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".user-name"}
  (Session info: headless chrome=95.0.4638.69)
For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'MacBook-Pro-3.local', ip: 'fe80:0:0:0:869:afaa:89ee:2f42%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.15.7', java.version: '1.8.0_302'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 95.0.4638.69, chrome: {chromedriverVersion: 95.0.4638.54 (d31a821ec901f..., userDataDir: /var/folders/fy/4f9mrb0n1fq...}, goog:chromeOptions: {debuggerAddress: localhost:62396}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: MAC, platformName: MAC, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: 968cb69072e7bbe6a92b2822d8ad26ee
*** Element info: {Using=css selector, value=.user-name}
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
    at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
    at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:323)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementByCssSelector(RemoteWebDriver.java:420)
    at org.openqa.selenium.By$ByCssSelector.findElement(By.java:431)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:315)
    at org.openqa.selenium.support.pagefactory.DefaultElementLocator.findElement(DefaultElementLocator.java:69)
    at org.openqa.selenium.support.pagefactory.AjaxElementLocator.access$001(AjaxElementLocator.java:39)
    at org.openqa.selenium.support.pagefactory.AjaxElementLocator$SlowLoadingElement.isLoaded(AjaxElementLocator.java:165)
    at org.openqa.selenium.support.ui.SlowLoadableComponent.get(SlowLoadableComponent.java:72)
    at org.openqa.selenium.support.pagefactory.AjaxElementLocator.findElement(AjaxElementLocator.java:95)
    ... 48 more
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Prozorov
  • 149
  • 9

2 Answers2

0

for this css selector :

.user-name

Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.

css that you should check :

.user-name

Steps to check:

Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the css and see, if your desired element is getting highlighted with 1/1 matching node.

If we have 1/1 matching node, Please make sure that :

  1. This web element is not under an iframe.
  2. This web element is not under a shadow root.
  3. You should not be on the new tab/windows launched by selenium.

If it falls under any category mentioned above, You would have to handle that particular scenario.

cruisepandey
  • 28,520
  • 6
  • 20
  • 38
  • Hey man i appreciate your time and contribution, i have added a screenshot and test of mine above. – Prozorov Nov 05 '21 at 09:49
  • You can check `//div[@class='icon-profile-container']//child::span[@class='user-name']` xpath, does it show 1/1 matching node ? Please refer how to check section above. – cruisepandey Nov 05 '21 at 10:08
  • Hey it locates //div[@class='icon-profile-container'] this way but if adding a child in a string it does not... – Prozorov Nov 05 '21 at 10:26
  • then that's the issue.. how many nodes for `//div[@class='icon-profile-container']//child::span[@class='user-name']` ? you would see something like 1/2 or 1/3 or something like that – cruisepandey Nov 05 '21 at 10:27
  • do you my if i message you in chat? – Prozorov Nov 05 '21 at 10:52
  • so it wasnt a child of icon-profile its //div[@class='header-menu-name']//child::span[@class='user-name'] – Prozorov Nov 05 '21 at 11:00
  • i have specified xpath and it worked but really xpath is not the way as i have read it mostly is better to use css this worked but i dont like it //body/div[@id='__next']/div[1]/div[1]/nav[1]/div[1]/div[6]/div[1]/div[1]/span[1] – Prozorov Nov 05 '21 at 11:08
  • css is better when it comes to performance, for this particular instance you may use CSS. Having said that, I would never recommend you to use the XPath `//body/div[@id='__next']/div[1]/div[1]/nav[1]/div[1]/div[6]/div[1]/div[1]/span[1] `, instead you could try to use some relative xpath. – cruisepandey Nov 05 '21 at 17:15
  • Also, I saw your comment on another answer, Just letting you know it really does not matter if you are using implicit wait, that is just for findElement. I would suggest to use explicit wait. – cruisepandey Nov 05 '21 at 17:17
  • @cruisepandey This comment _it really does not matter if you are using implicit wait_ is totally wrong and misleading. Check the documentation. – undetected Selenium Nov 05 '21 at 18:56
  • You should read the documentation carefully, there's nothing called implicit wait anymore. – cruisepandey Nov 06 '21 at 03:18
0

AjaxElementLocatorFactory

AjaxElementLocatorFactory is a lazy load concept in Page Factory pattern to identify WebElements only when they are used in any operation i.e. a timeOut for a WebElement can be assigned to the Object page class with the help of AjaxElementLocatorFactory.

So ideally you need to remove the implicitlyWait as:

Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.


NoSuchElementException indicates element wasn't located.

To locate the element you can use either of the following Locator Strategies:

  • Using css_selector:

    div.header-menu-item > div.header-menu-name span.user-name
    
  • Using xpath:

    //div[@class='header-menu-item']/div[@class='header-menu-item']//span[@class='user-name']
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352