mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-07 03:22:23 +00:00
Refactoring for the usage of the "Page Object" pattern and waiting for
pending AJAX calls.
This commit is contained in:
1 parent
23b753772f
commit
31c2f5caf6
26 files changed
+723
-159
No files matched your search
@@ -3,5 +3,6 @@
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="resources"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -5,5 +5,5 @@ Bundle-SymbolicName: com.sap.sailing.selenium.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Require-Bundle: org.openqa.selenium.osgi;bundle-version="2.23.1",
|
||||
org.junit4;bundle-version="4.8.2"
|
||||
Require-Bundle: org.junit4;bundle-version="4.8.2",
|
||||
org.openqa.selenium.osgi;bundle-version="2.23.1"
|
||||
@@ -1,4 +1,5 @@
|
||||
source.. = src/
|
||||
source.. = src/,\
|
||||
resources/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Configuration file for the test environment. This file is used for the configuration of the environment for the
|
||||
executions of the integration tests. For the execution in a local environment you should make a copy of this file,
|
||||
change it accordingly to your local setup (eg. browser(s) to use for the tests) and adjust the property
|
||||
"parameters.integration-tests" in your user specific settings.xml to point to your local copy of this file.
|
||||
-->
|
||||
<test-environment xmlns="http://www.sapsailing.com/test-environment"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.sapsailing.com/test-environment ./test-environment-configuration.xsd ">
|
||||
|
||||
<!--
|
||||
The context root (the server) against which the tests should be executed.
|
||||
-->
|
||||
<context-root>http://riccardo:riccardo@localhost:8888/</context-root>
|
||||
|
||||
<!--
|
||||
In this section necessary system properties for the different web drivers can be provided if needed. For more
|
||||
informations about available properties see the following sides:
|
||||
|
||||
- http://code.google.com/p/selenium/wiki/ChromeDriver
|
||||
- http://code.google.com/p/selenium/wiki/FirefoxDriver
|
||||
- http://code.google.com/p/selenium/wiki/InternetExplorerDriver
|
||||
- http://code.google.com/p/selenium/wiki/OperaDriver
|
||||
- http://code.google.com/p/selenium/wiki/SafariDriver
|
||||
- http://code.google.com/p/selenium/wiki/RemoteWebDriverServer
|
||||
|
||||
NOTE: For the Chrome and the InternetExplorer driver an additional "server", which acts as a bridge between the
|
||||
browser and the driver, is needed.
|
||||
-->
|
||||
|
||||
<system-properties>
|
||||
<!--
|
||||
<system-property>
|
||||
<name>webdriver.chrome.driver</name>
|
||||
<value>[path to]\chromedriver.exe</value>
|
||||
</system-property>
|
||||
-->
|
||||
<system-property>
|
||||
<name>webdriver.firefox.bin</name>
|
||||
<value>D:\Internet\Firefox\firefox.exe</value>
|
||||
</system-property>
|
||||
</system-properties>
|
||||
|
||||
|
||||
<!--
|
||||
The driver definitions define all web drivers (browsers) which should be used for the execution of the tests. This
|
||||
means that each test will be executed once for each driver defined here. This allows to perform the tests with
|
||||
different browsers to validate the proper functionality of the application across different browsers.
|
||||
|
||||
The capabilities section can be used for fine tuning of the driver (e.g. version). For more informations see the
|
||||
pages mentioned above.
|
||||
-->
|
||||
<driver-definition class="org.openqa.selenium.firefox.FirefoxDriver">
|
||||
<!--
|
||||
<capabilities>
|
||||
<capability>
|
||||
<name>version</name>
|
||||
<value>14.0.0</value>
|
||||
</capability>
|
||||
</capabilities>
|
||||
-->
|
||||
</driver-definition>
|
||||
|
||||
<!--
|
||||
<driver-definition class="org.openqa.selenium.chrome.ChromeDriver" />
|
||||
-->
|
||||
</test-environment>
|
||||
File renamed without changes.
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import org.openqa.selenium.JavascriptExecutor;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.support.ui.ExpectedCondition;
|
||||
|
||||
public class AjaxCallsComplete implements ExpectedCondition<Boolean> {
|
||||
@Override
|
||||
public Boolean apply(WebDriver driver) {
|
||||
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||
|
||||
return (Boolean) executor.executeScript("return (window.PENDING_AJAX_CALLS.numberOfPendingCalls() === 0)");
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
public class BySeleniumId extends By {
|
||||
/**
|
||||
* <p>XPath expression for the search of an element with a given selenium identifier. The search is performed in the
|
||||
* specified context (web driver or web element) and returns the first matching element which is one or more
|
||||
* levels deep in the current context.</p>
|
||||
*/
|
||||
private static final MessageFormat BY_SELENIUM_ID = new MessageFormat(".//*[@selenium-id=\"{0}\"]");
|
||||
|
||||
private String id;
|
||||
|
||||
public BySeleniumId(String id) {
|
||||
super();
|
||||
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
// TODO [D049941]: Verify that the element closest to the context is returned in the case that several elements
|
||||
// are found!
|
||||
@Override
|
||||
public WebElement findElement(SearchContext context) {
|
||||
return super.findElement(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebElement> findElements(SearchContext context) {
|
||||
return context.findElements(By.xpath(BY_SELENIUM_ID.format(new Object[] {this.id})));
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import org.openqa.selenium.SearchContext;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public interface ElementSearchCondition<T> extends Function<SearchContext, T> {
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.StaleElementReferenceException;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
public class ElementSearchConditions {
|
||||
|
||||
/**
|
||||
* An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that
|
||||
* the element is not only displayed but also has a height and width that is greater than 0.
|
||||
*
|
||||
* @param locator
|
||||
* used to find the element
|
||||
* @return
|
||||
* the WebElement once it is located and visible
|
||||
*/
|
||||
public static ElementSearchCondition<WebElement> visibilityOfElementLocated(final By locator) {
|
||||
return new ElementSearchCondition<WebElement>() {
|
||||
@Override
|
||||
public WebElement apply(SearchContext context) {
|
||||
try {
|
||||
return elementIfVisible(findElement(context, locator));
|
||||
} catch (StaleElementReferenceException exception) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "visibility of element located by " + locator;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static WebElement elementIfVisible(WebElement element) {
|
||||
return element.isDisplayed() ? element : null;
|
||||
}
|
||||
|
||||
private static WebElement findElement(SearchContext context, By by) {
|
||||
return context.findElement(by);
|
||||
}
|
||||
|
||||
private static List<WebElement> findElements(SearchContext context, By by) {
|
||||
return context.findElements(by);
|
||||
}
|
||||
|
||||
private ElementSearchConditions() {
|
||||
// Utility class
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.selenium.test.core;
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
+16
-25
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.selenium.test.core;
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.util.Map.Entry;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.Runner;
|
||||
|
||||
import org.junit.runner.notification.Failure;
|
||||
import org.junit.runner.notification.RunNotifier;
|
||||
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
@@ -25,8 +26,8 @@ import org.openqa.selenium.WebDriver;
|
||||
|
||||
import org.openqa.selenium.remote.DesiredCapabilities;
|
||||
|
||||
import com.sap.sailing.selenium.test.core.TestEnvironmentConfiguration.DriverDefinition;
|
||||
import com.sap.sailing.selenium.test.core.impl.TestEnvironmentImpl;
|
||||
import com.sap.sailing.selenium.core.TestEnvironmentConfiguration.DriverDefinition;
|
||||
import com.sap.sailing.selenium.core.impl.TestEnvironmentImpl;
|
||||
|
||||
public class Selenium extends ParentRunner<Runner> {
|
||||
private final List<Runner> children;
|
||||
@@ -88,7 +89,8 @@ public class Selenium extends ParentRunner<Runner> {
|
||||
|
||||
private TestEnvironmentImpl environment;
|
||||
|
||||
public SeleniumJUnit4ClassRunner(Class<?> klass, String root, DriverDefinition definition) throws InitializationError {
|
||||
public SeleniumJUnit4ClassRunner(Class<?> klass, String root, DriverDefinition definition)
|
||||
throws InitializationError {
|
||||
super(klass);
|
||||
|
||||
this.root = root;
|
||||
@@ -110,37 +112,26 @@ public class Selenium extends ParentRunner<Runner> {
|
||||
|
||||
List<FrameworkField> fields = testClass.getAnnotatedFields(Managed.class);
|
||||
|
||||
this.environment = createTestEnvironment();
|
||||
|
||||
for (final FrameworkField field : fields) {
|
||||
field.getField().setAccessible(true);
|
||||
field.getField().set(test, this.environment);
|
||||
|
||||
//FieldUtils.writeField(field.getField(), test, selenium, true);
|
||||
}
|
||||
|
||||
// final List<TestRule> rules = this.getTestRules(test);
|
||||
//
|
||||
// for (final TestRule rule : rules) {
|
||||
// final Field[] ruleFields = rule.getClass().getDeclaredFields();
|
||||
// for (final Field ruleField : ruleFields) {
|
||||
// if (ruleField.getAnnotation(annotationType) != null) {
|
||||
// FieldUtils.writeField(ruleField, rule, selenium, true);
|
||||
// } else if (ruleField.getAnnotation(SeleniumBrowser.class) != null) {
|
||||
// FieldUtils.writeField(ruleField, rule, browser, true);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final RunNotifier notifier) {
|
||||
try {
|
||||
super.run(notifier);
|
||||
} finally {
|
||||
this.environment.close();
|
||||
this.environment = createTestEnvironment();
|
||||
|
||||
try {
|
||||
super.run(notifier);
|
||||
} finally {
|
||||
this.environment.close();
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
notifier.fireTestFailure(new Failure(getDescription(), exception));
|
||||
}
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.support.pagefactory.Annotations;
|
||||
import org.openqa.selenium.support.pagefactory.ElementLocator;
|
||||
|
||||
import org.openqa.selenium.support.ui.FluentWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
public class SeleniumElementLocator implements ElementLocator {
|
||||
private final SearchContext context;
|
||||
private final FluentWait<SearchContext> wait;
|
||||
private final boolean useCache;
|
||||
|
||||
private final By by;
|
||||
|
||||
private WebElement element;
|
||||
private List<WebElement> elements;
|
||||
|
||||
public SeleniumElementLocator(SearchContext context, Field field, int timeOut) {
|
||||
this(context, field, timeOut, 250);
|
||||
}
|
||||
|
||||
public SeleniumElementLocator(SearchContext context, Field field, int timeOut, int intervall) {
|
||||
this.context = context;
|
||||
|
||||
this.wait = new FluentWait<>(this.context);
|
||||
this.wait.withTimeout(timeOut, TimeUnit.SECONDS);
|
||||
this.wait.pollingEvery(intervall, TimeUnit.MILLISECONDS);
|
||||
this.wait.ignoring(NoSuchElementException.class);
|
||||
|
||||
Annotations annotations = new Annotations(field);
|
||||
this.useCache = annotations.isLookupCached();
|
||||
this.by = annotations.buildBy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebElement findElement() {
|
||||
if(this.useCache && this.element != null) {
|
||||
return this.element;
|
||||
}
|
||||
|
||||
this.element = this.wait.until(new Function<SearchContext, WebElement>() {
|
||||
@Override
|
||||
public WebElement apply(SearchContext context) {
|
||||
WebElement element = context.findElement(SeleniumElementLocator.this.getBy());
|
||||
|
||||
return (isElementUsable(element) ? element : null);
|
||||
}
|
||||
});
|
||||
|
||||
return this.element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebElement> findElements() {
|
||||
if(this.useCache && this.elements != null) {
|
||||
return this.elements;
|
||||
}
|
||||
|
||||
this.elements = this.wait.until(new Function<SearchContext, List<WebElement>>() {
|
||||
@Override
|
||||
public List<WebElement> apply(SearchContext context) {
|
||||
return context.findElements(SeleniumElementLocator.this.getBy());
|
||||
}
|
||||
});
|
||||
|
||||
return this.elements;
|
||||
}
|
||||
|
||||
public By getBy() {
|
||||
return this.by;
|
||||
}
|
||||
|
||||
protected boolean isElementUsable(WebElement element) {
|
||||
return element.isDisplayed();
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.openqa.selenium.SearchContext;
|
||||
|
||||
import org.openqa.selenium.support.pagefactory.ElementLocator;
|
||||
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
|
||||
|
||||
public class SeleniumElementLocatorFactory implements ElementLocatorFactory {
|
||||
private SearchContext context;
|
||||
private final int timeOut;
|
||||
private final int intervall;
|
||||
|
||||
public SeleniumElementLocatorFactory(SearchContext context, int timeOut) {
|
||||
this(context, timeOut, 250);
|
||||
}
|
||||
|
||||
public SeleniumElementLocatorFactory(SearchContext context, int timeOut, int intervall) {
|
||||
this.context = context;
|
||||
this.timeOut = timeOut;
|
||||
this.intervall = intervall;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementLocator createLocator(Field field) {
|
||||
return new SeleniumElementLocator(this.context, field, this.timeOut, this.intervall);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.selenium.test.core;
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
+1
-2
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.selenium.test.core;
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -108,7 +108,6 @@ public class TestEnvironmentConfiguration {
|
||||
Schema schema = schemaFactory.newSchema(new StreamSource(TEST_ENVIRONMENT_SCHEMA));
|
||||
|
||||
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
|
||||
builderFactory.setValidating(true);
|
||||
builderFactory.setNamespaceAware(true);
|
||||
builderFactory.setSchema(schema);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.selenium.test.core;
|
||||
package com.sap.sailing.selenium.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package com.sap.sailing.selenium.test.core.impl;
|
||||
package com.sap.sailing.selenium.core.impl;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import com.sap.sailing.selenium.test.core.TestEnvironment;
|
||||
import com.sap.sailing.selenium.core.TestEnvironment;
|
||||
|
||||
public class TestEnvironmentImpl implements TestEnvironment {
|
||||
private WebDriver driver;
|
||||
+14
-35
@@ -8,25 +8,20 @@ import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.OutputType;
|
||||
import org.openqa.selenium.TakesScreenshot;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.remote.Augmenter;
|
||||
import org.openqa.selenium.remote.RemoteWebDriver;
|
||||
|
||||
import com.sap.sailing.selenium.test.core.Managed;
|
||||
import com.sap.sailing.selenium.test.core.Selenium;
|
||||
import com.sap.sailing.selenium.test.core.TestEnvironment;
|
||||
import com.sap.sailing.selenium.core.Managed;
|
||||
import com.sap.sailing.selenium.core.Selenium;
|
||||
import com.sap.sailing.selenium.core.TestEnvironment;
|
||||
|
||||
@RunWith(Selenium.class)
|
||||
public abstract class AbstractSeleniumTest {
|
||||
private static final String NOT_SUPPORTED_IMAGE = "/com/sap/sailing/selenium/resources/not-supported.png";
|
||||
|
||||
@Managed
|
||||
protected TestEnvironment environment;
|
||||
@@ -38,40 +33,21 @@ public abstract class AbstractSeleniumTest {
|
||||
protected WebDriver getWebDriver() {
|
||||
return this.environment.getWebDriver();
|
||||
}
|
||||
|
||||
protected WebElement findElementBySeleniumId(String id) {
|
||||
return findElementBySeleniumId(getWebDriver(), id);
|
||||
}
|
||||
|
||||
protected WebElement findElementBySeleniumId(WebDriver driver, String id) {
|
||||
return driver.findElement(By.xpath("//*[@selenium-id='" + id + "']"));
|
||||
}
|
||||
|
||||
protected WebElement findElementBySeleniumId(WebElement element, String id) {
|
||||
return element.findElement(By.xpath("//*[@selenium-id='" + id + "']"));
|
||||
}
|
||||
|
||||
protected List<WebElement> findElementsBySeleniumId(WebDriver driver, String id) {
|
||||
return driver.findElements(By.xpath("//*[@selenium-id='" + id + "']"));
|
||||
}
|
||||
|
||||
protected List<WebElement> findElementsBySeleniumId(WebElement element, String id) {
|
||||
return element.findElements(By.xpath("//*[@selenium-id='" + id + "']"));
|
||||
}
|
||||
|
||||
|
||||
protected void captureScreenshot() throws IOException {
|
||||
WebDriver driver = getWebDriver();
|
||||
|
||||
if(driver instanceof RemoteWebDriver) {
|
||||
driver = new Augmenter().augment(driver);
|
||||
}
|
||||
// if(driver instanceof RemoteWebDriver) {
|
||||
// driver = new Augmenter().augment(driver);
|
||||
// }
|
||||
|
||||
File source = getScreenshotNotSupportedImage();
|
||||
|
||||
if(driver instanceof TakesScreenshot)
|
||||
source = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
|
||||
|
||||
// TODO: Use the right path
|
||||
// TODO: Use the right path.
|
||||
// QUESTION: What is the right path?
|
||||
String path = "./target/screenshots/" + source.getName();
|
||||
|
||||
Files.copy(source.toPath(), new File(path).toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
@@ -79,7 +55,10 @@ public abstract class AbstractSeleniumTest {
|
||||
|
||||
private File getScreenshotNotSupportedImage() {
|
||||
try {
|
||||
URL pictureURL = AbstractSeleniumTest.class.getResource("not-supported.png");
|
||||
//BundleContext context = SeleniumTestsActivator.getContext();
|
||||
//Bundle bundle = context.getBundle();
|
||||
//URL pictureURL = bundle.getResource("/com/sap/sailing/selenium/resources/not-supported.png");
|
||||
URL pictureURL = AbstractSeleniumTest.class.getResource(NOT_SUPPORTED_IMAGE);
|
||||
URI pictureURI = pictureURL.toURI();
|
||||
|
||||
return new File(pictureURI);
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.sap.sailing.selenium.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.support.PageFactory;
|
||||
|
||||
import org.openqa.selenium.support.ui.FluentWait;
|
||||
|
||||
import com.sap.sailing.selenium.core.AjaxCallsComplete;
|
||||
import com.sap.sailing.selenium.core.BySeleniumId;
|
||||
import com.sap.sailing.selenium.core.SeleniumElementLocatorFactory;
|
||||
|
||||
public class PageObject {
|
||||
protected static final int DEFAULT_TIMEOUT = 60;
|
||||
|
||||
protected final WebDriver driver;
|
||||
protected final SearchContext context;
|
||||
|
||||
public PageObject(WebDriver driver) {
|
||||
this(driver, driver);
|
||||
}
|
||||
|
||||
public PageObject(WebDriver driver, SearchContext context) {
|
||||
this.driver = driver;
|
||||
this.context = context;
|
||||
|
||||
initElements();
|
||||
}
|
||||
|
||||
protected void initElements() {
|
||||
PageFactory.initElements(new SeleniumElementLocatorFactory(this.context, getTimeOut()), this);
|
||||
}
|
||||
|
||||
protected int getTimeOut() {
|
||||
return DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
protected WebElement findElementBySeleniumId(String id) {
|
||||
return findElementBySeleniumId(this.context, id);
|
||||
}
|
||||
|
||||
protected WebElement findElementBySeleniumId(SearchContext context, String id) {
|
||||
return context.findElement(new BySeleniumId(id));
|
||||
}
|
||||
|
||||
protected List<WebElement> findElementsBySeleniumId(String id) {
|
||||
return findElementsBySeleniumId(this.context, id);
|
||||
}
|
||||
|
||||
protected List<WebElement> findElementsBySeleniumId(SearchContext context, String id) {
|
||||
return context.findElements(new BySeleniumId(id));
|
||||
}
|
||||
|
||||
protected void waitForAjaxRequests() {
|
||||
waitForAjaxRequests(30, 5);
|
||||
}
|
||||
|
||||
protected void waitForAjaxRequests(int timeout, int polling) {
|
||||
FluentWait<WebDriver> wait = new FluentWait<>(this.driver);
|
||||
wait.withTimeout(timeout, TimeUnit.SECONDS);
|
||||
wait.pollingEvery(polling, TimeUnit.SECONDS);
|
||||
|
||||
wait.until(new AjaxCallsComplete());
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
(function() {
|
||||
function createNamespace(namespace) {
|
||||
parts = namespace.split('.');
|
||||
var base = window;
|
||||
|
||||
for(var i = 0; i < namespace.length; i++) {
|
||||
base[parts[i]] = base[parts[i]] || {};
|
||||
base = base[parts[i]];
|
||||
}
|
||||
|
||||
return base; //return resulting namespace object
|
||||
}
|
||||
|
||||
var namespace = createNamespace("org.openqa.selenium");
|
||||
|
||||
if(namespace.pendingCalls)
|
||||
return;
|
||||
|
||||
namespace.pendingCalls = 0;
|
||||
|
||||
XMLHttpRequest.prototype.oldSend = XMLHttpRequest.prototype.send;
|
||||
|
||||
var newSend = function(data) {
|
||||
var xhr = this;
|
||||
|
||||
namespace.pendingCalls++;
|
||||
|
||||
var callFinished = function() {
|
||||
namespace.pendingCalls--;
|
||||
};
|
||||
|
||||
xhr.addEventListener("abort", callFinished, false);
|
||||
xhr.addEventListener("load", callFinished, false);
|
||||
xhr.addEventListener("error", callFinished, false);
|
||||
xhr.addEventListener("timeout", callFinished, false);
|
||||
|
||||
xhr.oldSend(data);
|
||||
}
|
||||
|
||||
XMLHttpRequest.prototype.send = newSend;
|
||||
}());
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.sap.sailing.selenium.test.adminconsole;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.Is.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import com.sap.sailing.selenium.test.AbstractSeleniumTest;
|
||||
import com.sap.sailing.selenium.test.adminconsole.pages.AdminConsolePage;
|
||||
import com.sap.sailing.selenium.test.adminconsole.pages.TracTracEventManagementPanel;
|
||||
|
||||
public class TestRaceFilterForTracTracEvents extends AbstractSeleniumTest {
|
||||
protected static final String BMW_CUP_JSON_URL = "http://kml.skitrac.traclive.dk/events/event_20120803_BMWCup/jsonservice.php";
|
||||
|
||||
@Test
|
||||
public void testNoFilter() throws IOException {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
|
||||
TracTracEventManagementPanel tracTracEvents = adminConsole.goToTracTracEvents();
|
||||
tracTracEvents.listRaces(BMW_CUP_JSON_URL);
|
||||
|
||||
assertThat(tracTracEvents.getTrackableRaces().size(), is(12));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("boxing")
|
||||
@Test
|
||||
public void testPartialFilter() {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
|
||||
TracTracEventManagementPanel tracTracEvents = adminConsole.goToTracTracEvents();
|
||||
tracTracEvents.listRaces(BMW_CUP_JSON_URL);
|
||||
tracTracEvents.setFilterForTrackableRaces("BMW Cup Race 1");
|
||||
|
||||
assertThat(tracTracEvents.getTrackableRaces().size(), is(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStratRacking() {
|
||||
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.sap.sailing.selenium.test.adminconsole;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.selenium.test.AbstractSeleniumTest;
|
||||
|
||||
import com.sap.sailing.selenium.test.adminconsole.pages.AdminConsolePage;
|
||||
import com.sap.sailing.selenium.test.adminconsole.pages.TracTracEventManagementPanel;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import static org.junit.matchers.JUnitMatchers.hasItem;
|
||||
|
||||
public class TestStartAndStopTrackingForTracTracEvents extends AbstractSeleniumTest {
|
||||
private static final String BMW_CUP_JSON_URL = "http://kml.skitrac.traclive.dk/events/event_20120803_BMWCup/jsonservice.php";
|
||||
private static final String NO_REGATTA = "No regatta";
|
||||
private static final String BMW_CUP_REGATTA = "BMW Cup (J80)";
|
||||
private static final String BMW_CUP_RACE_8 = "BMW Cup Race 8";
|
||||
|
||||
@Test
|
||||
public void testStartTrackingWithoutCorrectRegatta() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartAndStopTrackingWithCorrectRegatta() {
|
||||
AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
|
||||
|
||||
TracTracEventManagementPanel tracTracEvents = adminConsole.goToTracTracEvents();
|
||||
tracTracEvents.listRaces(BMW_CUP_JSON_URL);
|
||||
//tracTracEvents.startTracking(BMW_CUP_RACE_8, BMW_CUP_REGATTA, false, false, false);
|
||||
|
||||
//assertThat(tracTracEvents.getTrackedRaces(), hasItem(12));
|
||||
|
||||
//tracTracEvents.stopTracking("BMW_CUP_RACE_8");
|
||||
|
||||
//assertThat(tracTracEvents.getTrackedRaces(), not(hasItem(12)));
|
||||
}
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
package com.sap.sailing.selenium.test.adminconsole;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import com.sap.sailing.selenium.test.AbstractSeleniumTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.support.ui.FluentWait;
|
||||
|
||||
public class TracTracEventManagementPanelUITest extends AbstractSeleniumTest {
|
||||
private static final String BMW_CUP_JSON_URL = "http://kml.skitrac.traclive.dk/events/event_20120803_BMWCup/jsonservice.php";
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
WebDriver driver = getWebDriver();
|
||||
|
||||
driver.get(getContextRoot() + "gwt/AdminConsole.html");
|
||||
|
||||
assertEquals("Title of the page does not match.", "SAP Sailing Analytics Administration Console", driver.getTitle());
|
||||
|
||||
WebElement tabPanel = findElementBySeleniumId("AdministrationTabs");
|
||||
WebElement tracTracTab = tabPanel.findElement(By.xpath("//div[@class='gwt-TabBarItem' and @role='tab']/div[text()='TracTrac Events']/.."));
|
||||
WebElement managementPanel = findElementBySeleniumId(tabPanel, "TracTracEventManagement");
|
||||
|
||||
tracTracTab.click();
|
||||
|
||||
FluentWait<WebElement> wait = new FluentWait<>(managementPanel);
|
||||
wait.withTimeout(30, TimeUnit.SECONDS);
|
||||
wait.pollingEvery(5, TimeUnit.SECONDS);
|
||||
wait.ignoring(NoSuchElementException.class);
|
||||
|
||||
WebElement urlField = wait.until(new Function<WebElement, WebElement>() {
|
||||
@Override
|
||||
public WebElement apply(WebElement element) {
|
||||
return findElementBySeleniumId(element, "JSONURL");
|
||||
}
|
||||
});
|
||||
urlField.clear();
|
||||
urlField.sendKeys(BMW_CUP_JSON_URL);
|
||||
|
||||
WebElement listRacesButton = findElementBySeleniumId(managementPanel, "ListRaces");
|
||||
listRacesButton.click();
|
||||
|
||||
wait.withTimeout(5, TimeUnit.MINUTES);
|
||||
wait.pollingEvery(10, TimeUnit.SECONDS);
|
||||
List<WebElement> trackableRaces = wait.until(new Function<WebElement, List<WebElement>>() {
|
||||
@Override
|
||||
public List<WebElement> apply(WebElement element) {
|
||||
WebElement availableRacesTabel = findElementBySeleniumId(element, "RacesTable");
|
||||
List<WebElement> elements = availableRacesTabel.findElements(By.xpath("//tbody/tr/td[1]/div[text()='BMW Cup']/../.."));
|
||||
return elements.size() > 0 ? elements : null;
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue("There should be 12 trackable races available.", trackableRaces.size() == 12);
|
||||
|
||||
WebElement trackWindCheckbox = findElementBySeleniumId(managementPanel, "TrackWind");
|
||||
trackWindCheckbox.click();
|
||||
|
||||
WebElement cupRace1 = trackableRaces.get(0);
|
||||
cupRace1.click();
|
||||
|
||||
// WebElement startTrackingButton = findElementBySeleniumId(managementPanel, "StartTracking");
|
||||
// startTrackingButton.click();
|
||||
//
|
||||
// wait.withTimeout(5, TimeUnit.MINUTES);
|
||||
// wait.pollingEvery(10, TimeUnit.SECONDS);
|
||||
// List<WebElement> trackedRaces = wait.until(new Function<WebElement, List<WebElement>>() {
|
||||
// @Override
|
||||
// public List<WebElement> apply(WebElement element) {
|
||||
// //WebElement trackedRacesTabel = driver.findElement(By.id(GWT_DEBUG_PREFIX + "RacesTable"));
|
||||
// List<WebElement> elements = new ArrayList<>();//trackedRacesTabel.findElements(By.xpath("//tbody/tr/td[1]/div[text()='BMW CUP']/../.."));
|
||||
// return elements.size() > 0 ? elements : null;
|
||||
// }
|
||||
// });
|
||||
|
||||
// TODO: Check, remove (and check remove)!
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.sap.sailing.selenium.test.adminconsole.pages;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.openqa.selenium.Alert;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebDriver.TargetLocator;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.security.UserAndPassword;
|
||||
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.How;
|
||||
|
||||
import org.openqa.selenium.support.ui.FluentWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sap.sailing.selenium.core.BySeleniumId;
|
||||
import com.sap.sailing.selenium.core.ElementSearchConditions;
|
||||
import com.sap.sailing.selenium.test.PageObject;
|
||||
|
||||
|
||||
public class AdminConsolePage extends PageObject {
|
||||
private static final String PAGE_TITLE = "SAP Sailing Analytics Administration Console";
|
||||
|
||||
private static final MessageFormat TAB_EXPRESSION = new MessageFormat(
|
||||
".//div[@class=\"gwt-TabBarItem\" and @role=\"tab\"]/div[text()=\"{0}\"]/..");
|
||||
|
||||
private static final String TRACTRAC_TAB_LABEL = "TracTrac Events";
|
||||
private static final String TRACTRAC_TAB_IDENTIFIER = "TracTracEventManagement";
|
||||
|
||||
public static AdminConsolePage goToPage(WebDriver driver, String root) {
|
||||
driver.get(root + "gwt/AdminConsole.html");
|
||||
|
||||
// FluentWait<WebDriver> wait = new FluentWait<>(driver);
|
||||
// wait.withTimeout(5, TimeUnit.SECONDS);
|
||||
// wait.pollingEvery(100, TimeUnit.MILLISECONDS);
|
||||
//
|
||||
// Alert alert = wait.until(new Function<WebDriver, Alert>() {
|
||||
// @Override
|
||||
// public Alert apply(WebDriver context) {
|
||||
// TargetLocator locator = context.switchTo();
|
||||
//
|
||||
// return locator.alert();
|
||||
// }
|
||||
// });
|
||||
// alert.authenticateUsing(new UserAndPassword("user", "password"));
|
||||
|
||||
return new AdminConsolePage(driver);
|
||||
}
|
||||
|
||||
@FindBy(how = How.XPATH, using = "//*[@selenium-id='AdministrationTabs']")
|
||||
private WebElement tabPanel;
|
||||
|
||||
private AdminConsolePage(WebDriver driver) {
|
||||
super(driver);
|
||||
|
||||
if(!PAGE_TITLE.equals(driver.getTitle())) {
|
||||
throw new IllegalStateException("This is not the administration console");
|
||||
}
|
||||
}
|
||||
|
||||
public TracTracEventManagementPanel goToTracTracEvents() {
|
||||
return new TracTracEventManagementPanel(this.driver, gotToTab(TRACTRAC_TAB_LABEL, TRACTRAC_TAB_IDENTIFIER));
|
||||
}
|
||||
|
||||
private WebElement gotToTab(String label, final String id) {
|
||||
String expression = TAB_EXPRESSION.format(new Object[] {label});
|
||||
WebElement tab = this.tabPanel.findElement(By.xpath(expression));
|
||||
|
||||
tab.click();
|
||||
|
||||
// Wait for the tab to become visible due to the used animations.
|
||||
FluentWait<WebElement> wait = new FluentWait<>(this.tabPanel);
|
||||
wait.withTimeout(30, TimeUnit.SECONDS);
|
||||
wait.pollingEvery(5, TimeUnit.SECONDS);
|
||||
|
||||
WebElement content = wait.until(ElementSearchConditions.visibilityOfElementLocated(new BySeleniumId(id)));
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package com.sap.sailing.selenium.test.adminconsole.pages;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.SearchContext;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
|
||||
import org.openqa.selenium.support.FindBy;
|
||||
import org.openqa.selenium.support.How;
|
||||
|
||||
import com.sap.sailing.selenium.test.PageObject;
|
||||
|
||||
public class TracTracEventManagementPanel extends PageObject {
|
||||
@FindBy(how = How.XPATH, using = ".//*[@selenium-id='JSONURL']")
|
||||
private WebElement jsonURLField;
|
||||
|
||||
@FindBy(how = How.XPATH, using = ".//*[@selenium-id='ListRaces']")
|
||||
private WebElement listRacesButton;
|
||||
|
||||
@FindBy(how = How.XPATH, using = ".//*[@selenium-id='FilterRaces']")
|
||||
private WebElement filterTrackableRacesField;
|
||||
|
||||
private WebElement trackWindCheckBox;
|
||||
private WebElement correctWindCheckbox;
|
||||
private WebElement simulateWithNowCheckbox;
|
||||
|
||||
public TracTracEventManagementPanel(WebDriver driver, SearchContext context) {
|
||||
super(driver, context);
|
||||
}
|
||||
|
||||
public void listRaces(String url) {
|
||||
this.jsonURLField.clear();
|
||||
this.jsonURLField.sendKeys(url);
|
||||
this.listRacesButton.click();
|
||||
|
||||
waitForAjaxRequests();
|
||||
}
|
||||
|
||||
public List<WebElement> getTrackableRaces() {
|
||||
WebElement availableRacesTabel = findElementBySeleniumId(this.context, "RacesTable");
|
||||
List<WebElement> elements = availableRacesTabel.findElements(By.xpath("./tbody/tr"));
|
||||
Iterator<WebElement> iterator = elements.iterator();
|
||||
|
||||
while(iterator.hasNext()) {
|
||||
WebElement element = iterator.next();
|
||||
|
||||
if(!element.isDisplayed())
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
// public List<String> getAvailableReggatasForTracking() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public String getReggataForTracking() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void setReggataForTracking(String regatta) {
|
||||
//
|
||||
// }
|
||||
|
||||
public void setFilterForTrackableRaces(String filter) {
|
||||
this.filterTrackableRacesField.clear();
|
||||
this.filterTrackableRacesField.sendKeys(filter);
|
||||
}
|
||||
|
||||
// public void setTrackSettings(boolean trackWind, boolean correctWind, boolean simulateWithNow) {
|
||||
// setSelection(this.trackWindCheckBox, trackWind);
|
||||
// setSelection(this.correctWindCheckbox, correctWind);
|
||||
// setSelection(this.simulateWithNowCheckbox, simulateWithNow);
|
||||
// }
|
||||
//
|
||||
// public void startTrackingForRace() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public void startTrackingForRaces() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void setSelection(WebElement checkbox, boolean selected) {
|
||||
// WebElement input = checkbox.findElement(By.tagName("input"));
|
||||
// if(input.isSelected() != selected)
|
||||
// input.click();
|
||||
// }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.sap.sailing.selenium.test.gwt.widgets;
|
||||
|
||||
public class CellTable {
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user