Bug 4339: There are test failures regarding multi window handling (e.g.

in IE). To fix this we now create a new WebDriver instance for new
windows to prevent those problems
This commit is contained in:
Steffen Schaefer
2018-07-30 14:46:19 +02:00
parent 915be6ff81
commit 29e628187b
6 changed files with 42 additions and 95 deletions
@@ -7,6 +7,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -173,13 +174,20 @@ public class SeleniumRunner extends ParentRunner<SeleniumJUnit4ClassRunner> {
Map<String, Object> capabilityDefinitions = this.definition.getCapabilities();
@SuppressWarnings("unchecked")
Class<WebDriver> clazz = (Class<WebDriver>) Class.forName(driverClassname);
DesiredCapabilities capabilities = new DesiredCapabilities(capabilityDefinitions);
Constructor<WebDriver> constructor = clazz.getConstructor(Capabilities.class);
WebDriver driver = constructor.newInstance(capabilities);
final Supplier<WebDriver> webDriverFactory = () -> {
DesiredCapabilities capabilities = new DesiredCapabilities(capabilityDefinitions);
try {
return constructor.newInstance(capabilities);
} catch (Exception e) {
throw new IllegalStateException(e);
}
};
File screenshots = resolveScreenshotFolder();
return new TestEnvironmentImpl(driver, this.root, screenshots);
return new TestEnvironmentImpl(webDriverFactory, this.root, screenshots);
} catch (Exception exception) {
throw exception;
}
@@ -1,10 +1,9 @@
package com.sap.sailing.selenium.core;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
/**
@@ -14,9 +13,9 @@ import org.openqa.selenium.WebDriver;
* Riccardo Nimser (D049941)
*/
public class WindowManager {
private static final String JAVA_SCRIPT = "window.open('%s', '_blank')";
private WebDriver driver;
private final WebDriver driver;
private final Supplier<WebDriver> webDriverFactory;
/**
* <p></p>
@@ -24,81 +23,26 @@ public class WindowManager {
* @param driver
*
*/
public WindowManager(WebDriver driver) {
public WindowManager(WebDriver driver, Supplier<WebDriver> webDriverFactory) {
this.driver = driver;
this.webDriverFactory = webDriverFactory;
setWindowMaximized();
}
/**
* <p>Returns a handle to the window witch is currently active.</p>
*
* @return
*
*/
private WebDriverWindow getCurrentWindow() {
return new WebDriverWindow(this.driver, this.driver.getWindowHandle());
}
/**
* <p></p>
*
* @return
*/
private WebDriverWindow openNewWindow() {
return openNewWindow(false);
}
private WebDriverWindow openNewWindow(boolean focus) {
return openNewWindow("", focus);
}
private WebDriverWindow openNewWindow(String url, boolean focus) {
WebDriverWindow window = new WebDriverWindow(this.driver, createWindow(url));
if(focus) {
window.switchToWindow();
}
return window;
}
private String createWindow(String url) {
// Record old handles
Set<String> oldHandles = this.driver.getWindowHandles();
executeScript(url != null ? url : "");
return getNewHandle(oldHandles);
}
private void executeScript(String url) {
JavascriptExecutor executor = (JavascriptExecutor) this.driver;
executor.executeScript(String.format(JAVA_SCRIPT, url));
}
private String getNewHandle(Set<String> oldHandles) {
Set<String> newHandles = this.driver.getWindowHandles();
newHandles.removeAll(oldHandles);
// Find the new window
for(String handle : newHandles)
return handle;
return null;
setWindowMaximized(this.driver);
}
public void withExtraWindow(BiConsumer<WebDriverWindow, WebDriverWindow> defaultAndExtraWindow) {
final WebDriverWindow defaultWindow = getCurrentWindow();
final WebDriverWindow extraWindow = openNewWindow();
final WebDriverWindow defaultWindow = new WebDriverWindow(this.driver, this.driver.getWindowHandle());
final WebDriver extraDriver = webDriverFactory.get();
final WebDriverWindow extraWindow = new WebDriverWindow(extraDriver, extraDriver.getWindowHandle());
extraWindow.switchToWindow();
setWindowMaximized();
setWindowMaximized(extraDriver);
defaultWindow.switchToWindow();
try {
defaultAndExtraWindow.accept(defaultWindow, extraWindow);
} finally {
try {
extraWindow.close();
extraDriver.quit();
} catch (Exception e) {
// This call may fail depending on the WebDriver being used
}
@@ -106,7 +50,7 @@ public class WindowManager {
}
}
private void setWindowMaximized() {
private void setWindowMaximized(WebDriver driver) {
try {
driver.manage().window().maximize();
} catch (Exception e) {
@@ -1,6 +1,7 @@
package com.sap.sailing.selenium.core.impl;
import java.io.File;
import java.util.function.Supplier;
import org.openqa.selenium.WebDriver;
@@ -29,12 +30,12 @@ public class TestEnvironmentImpl implements TestEnvironment {
* @param screenshotsFolder
* The folder where screenshots should be stored.
*/
public TestEnvironmentImpl(WebDriver driver, String root, File screenshotsFolder) {
this.driver = driver;
public TestEnvironmentImpl(Supplier<WebDriver> webDriverFactory, String root, File screenshotsFolder) {
this.driver = webDriverFactory.get();
this.root = root;
this.screenshotsFolder = screenshotsFolder;
this.manager = new WindowManager(driver);
this.manager = new WindowManager(driver, webDriverFactory);
}
@Override
@@ -63,8 +63,8 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
super.setUp();
}
private TrackedRacesCompetitorsPanelPO goToCompetitorsPanel() {
final AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
private TrackedRacesCompetitorsPanelPO goToCompetitorsPanel(WebDriver driver) {
final AdminConsolePage adminConsole = AdminConsolePage.goToPage(driver, getContextRoot());
final TrackedRacesCompetitorsPanelPO competitorsPanel = adminConsole.goToTrackedRacesCompetitors();
return competitorsPanel;
}
@@ -72,8 +72,8 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
@Test
public void testMaintenanceOfSelectionAfterDataChanges() {
this.environment.getWindowManager().withExtraWindow((windowForSelection, windowForEdit) -> {
windowForEdit.switchToWindow();
final TrackedRacesCompetitorsPanelPO competitorsPanel = goToCompetitorsPanel();
final TrackedRacesCompetitorsPanelPO competitorsPanel = goToCompetitorsPanel(
windowForEdit.switchToWindow());
for (int i = 0; i < 2; i++) {
TrackedRacesCompetitorEditDialogPO dialog = competitorsPanel.pushAddCompetitorButton();
@@ -100,8 +100,8 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
}
assertTrue(found);
windowForSelection.switchToWindow();
TrackedRacesCompetitorsPanelPO competitorPanelForSelection = goToCompetitorsPanel();
TrackedRacesCompetitorsPanelPO competitorPanelForSelection = goToCompetitorsPanel(
windowForSelection.switchToWindow());
found = false;
for (final CompetitorEntry it : competitorPanelForSelection.getCompetitorTable().getEntries()) {
String itName = it.getName();
@@ -195,7 +195,6 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
@Test
public void testRefreshOfDependingUIElements() {
this.environment.getWindowManager().withExtraWindow((windowForSelection, windowForEdit) -> {
windowForSelection.switchToWindow();
setUpTestRefreshOfDependingUIElements();
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
SmartphoneTrackingEventManagementPanelPO smartphoneTrackingPanel = adminConsole.goToSmartphoneTrackingPanel();
@@ -217,9 +216,7 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
assertEquals(5, anzRaceColumns);
// Open a second window & setup second window
windowForEdit.switchToWindow();
AdminConsolePage adminConsoleForEdit = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
AdminConsolePage adminConsoleForEdit = AdminConsolePage.goToPage(windowForEdit.switchToWindow(), getContextRoot());
RegattaStructureManagementPanelPO regattaStructure = adminConsoleForEdit.goToRegattaStructure();
RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta);
@@ -79,8 +79,8 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest {
assertThat(races.size(), equalTo(5));
assertThat(table.getEntries().size(), equalTo(28)); // the regatta already has the races linked; regatta leaderboard obtains competitors from regatta
adminConsoleWindow.switchToWindow();
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
AdminConsolePage adminConsole = AdminConsolePage.goToPage(adminConsoleWindow.switchToWindow(), getContextRoot());
LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString());
@@ -121,8 +121,7 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest {
leaderboardDetails.linkRace(this.leaderboardRaces.get(3), this.trackedRaces.get(3));
leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4));
// Open the leaderboard in our second window
leaderboardWindow.switchToWindow();
LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false);
LeaderboardPage leaderboard = LeaderboardPage.goToPage(leaderboardWindow.switchToWindow(), getContextRoot(), LEADERBOARD, false);
LeaderboardTablePO table = leaderboard.getLeaderboardTable();
// Go back to the administration console and delete third race
adminConsoleWindow.switchToWindow();
@@ -157,9 +156,7 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest {
leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4));
// Open the leaderboard in our second window
leaderboardWindow.switchToWindow();
LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false);
LeaderboardPage leaderboard = LeaderboardPage.goToPage(leaderboardWindow.switchToWindow(), getContextRoot(), LEADERBOARD, false);
LeaderboardTablePO table = leaderboard.getLeaderboardTable();
// Go back to the administration console and rename the first race
@@ -61,8 +61,7 @@ public class TestSwitchingOffStartOfRaceInference extends AbstractSeleniumTest {
@Test
public void testCorrectDisplayOfRaceColumnWithAndWithoutStartTimeInference() {
this.environment.getWindowManager().withExtraWindow((adminConsoleWindow, leaderboardWindow) -> {
leaderboardWindow.switchToWindow();
LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, /* race details */ false);
LeaderboardPage leaderboard = LeaderboardPage.goToPage(leaderboardWindow.switchToWindow(), getContextRoot(), LEADERBOARD, /* race details */ false);
LeaderboardTablePO leaderboardTable = leaderboard.getLeaderboardTable();
List<String> races = leaderboardTable.getRaceNames();
assertThat("Expected only D3", races, equalTo(Arrays.asList("D3")));
@@ -78,6 +77,7 @@ public class TestSwitchingOffStartOfRaceInference extends AbstractSeleniumTest {
RegattaEditDialogPO regattaEditDialog = regattaList.editRegatta(regatta);
regattaEditDialog.setUseStartTimeInference(false);
regattaEditDialog.pressOk();
leaderboardWindow.switchToWindow();
leaderboard.refresh();
for (LeaderboardEntry e : leaderboardTable.getEntries()) {