Test uses the same function containing action twice. On first run it is working correctly and the test case is passed. However running the same function in next case does not trigger the action properly. What I could see so far is that the program thinks that the action is performed, because it fails on the next step, which cannot be done if previous one is not working.
The code is run on Chrome and Firefox. Chrome is working correctly, Firefox not.
private Actions actions = new Actions(driver);
@FindBy(css = "div.o-dropdown:nth-child(3)")
public WebElement myAccountBtn;
public void hoverProfileGoToManageProfiles() {
WebElement topNavBar = driver.findElement(By.cssSelector(".c-navbar__container"));
wait.until(ExpectedConditions.invisibilityOf(loadingSpinner));
wait.until(ExpectedConditions.elementToBeClickable(topNavBar));
performHoverManageProfiles();
}
public void performHoverManageProfiles() {
actions.moveToElement(myAccountBtn).perform();
WebElement manageProfilesBtn = driver.findElement(By.xpath("//*[@id=\"app\"]/nav[1]/div/div[2]/div[1]/div[2]/div/a[1]"));
WebElement clickableManageProfilesBtn = wait.until(ExpectedConditions.elementToBeClickable(manageProfilesBtn));
clickableManageProfilesBtn.click();
}
As you can see, in performHoverManageProfiles() there's the WebElement which can be found only after action (hover) is done.
I have tried moving creation of WebElement into the function so it's found on each run. Also the pasted code is already after some changes, that's why it may be messy, but so far the result is the same - works on Chrome, does not on Firefox.
Also tried clearing the myAccountBtn after each run alongside creating it at the beginning of function with no success as well.
Also I thought that maybe it is the matter of performance and maybe Firefox is too fast, so I added both Thread.sleep and fluent wait until the website is loaded, but again with no success.
CodePudding user response:
Turns out that Actions remember their state so one action won't be done twice in one run. To mitigate that, input state has to be reset after the performance, so the Actions think that it will be first run. To do this I've added following code at the bottom of the function
((RemoteWebDriver) driver).resetInputState();
As a result, entire function looks like this:
public void performHoverManageProfiles() {
actions.moveToElement(myAccountBtn).perform();
WebElement manageProfilesBtn = driver.findElement(By.xpath("//*[@id=\"app\"]/nav[1]/div/div[2]/div[1]/div[2]/div/a[1]"));
WebElement clickableManageProfilesBtn = wait.until(ExpectedConditions.elementToBeClickable(manageProfilesBtn));
clickableManageProfilesBtn.click();
((RemoteWebDriver) driver).resetInputState();
}
And the code is working correctly, doing the second action on each run as expected.