0

I have around 13 test classes, and this setting runs classes in parallel just fine:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Office Suite" thread-count="5" parallel="classes">
    <test name="Office Test" allow-return-values="true">
        <packages>
            <package name="testSuite.*"/>
        </packages>
    </test>
</suite>

However, when I am trying to run on a method level, I get problems:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Office Suite" thread-count="5" parallel="methods">
    <test name="Office Test" allow-return-values="true">
        <packages>
            <package name="testSuite.*"/>
        </packages>
    </test>
</suite>

I start seeing org.openqa.selenium.NoSuchElementException: Timed out after 5 seconds. Unable to locate the element.

Also this setting doesn't work:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Office Suite" thread-count="5" parallel="methods">
    <test name="Office Test" allow-return-values="true">
        <classes>
            <class name="testSuite.CustomerProfileBillingTest"/>
            <class name="testSuite.CustomerProfileTest"/>
            <class name="testSuite.CustomerSearchPageTest"/>
            <class name="testSuite.HomePageTest"/>
            <class name="testSuite.HomeZoneTest"/>
            <class name="testSuite.ImportLogTest"/>
            <class name="testSuite.InfleetPageTest"/>
            <class name="testSuite.LoginPageTest"/>
            <class name="testSuite.MembersArea1Test"/>
            <class name="testSuite.MembersArea2Test"/>
            <class name="testSuite.MembersArea3Test"/>
            <class name="testSuite.PromoPageTest"/>
            <class name="testSuite.TicketsTest"/>
        </classes>
    </test>
</suite>

Here is test:

@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception {
    DriverFactory.french = false;
    WEB_DRIVER_THREAD_LOCAL.set(new EventFiringWebDriver(DriverFactory.getDriver(TestUtil.getTargetBrowser())).register(new WebEventListener()));

    on = new Pages(WEB_DRIVER_THREAD_LOCAL.get());
    wait = new WebDriverWait(WEB_DRIVER_THREAD_LOCAL.get(), TestUtil.ELEMENT_PRESENT_WAIT);
}

@Test(groups = {"registration"})
public void verifyCustomerCanRectifyError() throws Exception{
    on.MembersRegistrationPage()
            .typeIn(on.MembersRegistrationPage().firstNameInput, customer.getFirstName())
            .click(on.MembersRegistrationPage().continueButton)
            .waitForVisibilityOfElement(on.MembersRegistrationPage().requestDrRecordButtonXPATH);

    assertTrue(on.MembersRegistrationPage().requestDrRecordHeader.isDisplayed());
}

Any idea why classes can be parallelized, but methods can't?

rcdsystems
  • 1,528
  • 1
  • 10
  • 11
Prostak
  • 3,565
  • 7
  • 35
  • 46

1 Answers1

0

NoSuchElementException means the driver is not finding an element and is timing out (which doesn't seem to be related to running tests in parallel. I suspect your issue is related to the way you are instantiating the browser, but I can't really tell, since you have references to code that appears to live elsewhere (e.g.: WEB_DRIVER_THREAD_LOCAL). This works fine for me (tested using gradle):

public class Sample {
  private static ThreadLocal<RemoteWebDriver> drivers = new ThreadLocal<>();

  @BeforeMethod
   public void setUp() throws MalformedURLException {
     RemoteWebDriver driver = new RemoteWebDriver(new URL("http://127.0.0.1:4444/wd/hub"), DesiredCapabilities.chrome());
     drivers.set(driver);
  }

  @Test
  public void testOne() {
    System.out.println("Launching Thread [" + Thread.currentThread().getId() + "]");
    getDriver().get("https://www.google.com");
  }

  @Test
  public void testTwo() {
    System.out.println("Launching Thread [" + Thread.currentThread().getId() + "]");
    getDriver().get("https://www.stackoverflow.com");
  }

  @AfterMethod
  public void tearDown() {
    getDriver().quit();
  }

  @AfterClass
  public void removeThread() {
    drivers.remove();
  }

  private RemoteWebDriver getDriver() {
    return drivers.get();
  }
}

Also, in your gradle file, make sure you define the name of the testng XML file you are using:

test {
  useTestNG() {
    useDefaultListeners = true 
    suites 'testng.xml' //location of the testng file
  }
}

TestNG file:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="Sample" parallel="methods" thread-count="2" >
  <test name="SampleTest" >
    <classes>
        <class name="Sample" />
    </classes>
  </test>
</suite>
rcdsystems
  • 1,528
  • 1
  • 10
  • 11
  • the thing is I do `WebDriver driver = new ChromeDriver();` in `@BeforeMethod` for both TestNG parallel settings. For 'classes' option it works, but for 'methods' option it throws above mentioned error. But I don't change `@BeforeMethod` for both of these options. How come do you think I need to change the logic for 'methods' TestNG option and put it inside the test instead? Isn't `@BeforeMethod` makes sense for 'methods' option? In other words: why would `@BeforeMethod` work for 'classes' option, but not work for 'methods' option? – Prostak Apr 24 '19 at 17:25
  • @Prostak can you update your question with the BeforeMethod and at least one test method? – rcdsystems Apr 25 '19 at 08:54
  • error has changed also with this config to this: `org.openqa.selenium.NoSuchElementException: Timed out after 5 seconds. Unable to locate the element` – Prostak Apr 25 '19 at 22:44
  • @rdcsystems, navigation to url also works for me, but interaction on the page does not work. In your example, can you add some interactions and assertion to verify? also, NoSuchElementException is actually a false error, because from screen shots i see all the elements available and fully loaded (remember that test cases execute just fine when `parallel="classes"`) – Prostak Apr 29 '19 at 20:47