New bundle for integration tests added.

This commit is contained in:
D049941 committed 2012-08-03 14:52:07 +02:00
1 parent b49e7a6b68
commit 99e7fd0e3e
17 files changed
+849

No files matched your search

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<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="output" path="bin"/>
</classpath>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.selenium.test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false
@@ -0,0 +1,9 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Selenium Integration Tests
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"
@@ -0,0 +1,5 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
test-environment-configuration.xsd
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 ">
<context-root>http://riccardo:riccardo@localhost:8888/</context-root>
<system-properties>
<system-property>
<name>webdriver.chrome.driver</name>
<value>D:\Development\Tools\Chrome Driver\chromedriver.exe</value>
</system-property>
<system-property>
<name>webdriver.firefox.bin</name>
<value>D:\Internet\Firefox\firefox.exe</value>
</system-property>
</system-properties>
<driver-defenition class="org.openqa.selenium.firefox.FirefoxDriver">
<!--
<capabilities>
<capability>
<name>version</name>
<value>14.0.0</value>
</capability>
</capabilities>
-->
</driver-defenition>
<!--
<driver-defenition class="org.openqa.selenium.chrome.ChromeDriver" />
-->
</test-environment>
+112
View File
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.selenium.test</artifactId>
<packaging>eclipse-test-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<configuration>
<!-- Skip the normal tests, we'll run them in the integration-test phase -->
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<excludes>
<exclude>**/core/**</exclude>
</excludes>
<appArgLine>-consoleLog -console -clean</appArgLine>
<!--
<argLine>-Dwebdriver.firefox.bin=D:\Internet\Firefox\firefox.exe -Xmx1024m -Djetty.home=${basedir}\..\target\configuration\jetty</argLine>
-->
<argLine>${tycho.argLine}</argLine>
<product>raceanalysis.product</product>
<application>raceanalysis.application</application>
<dependencies>
<dependency>
<type>eclipse-feature</type>
<artifactId>com.sap.sailing.feature</artifactId>
<version>0.0.0</version>
</dependency>
<dependency>
<type>eclipse-feature</type>
<artifactId>com.sap.sailing.feature.runtime</artifactId>
<version>0.0.0</version>
</dependency>
</dependencies>
<bundleStartLevel>
<bundle>
<id>com.sap.sailing.ess40.resultimport</id>
<level>3</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>com.sap.sailing.gwt.ui</id>
<level>4</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>com.sap.sailing.kiworesultimport</id>
<level>3</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>com.sap.sailing.server</id>
<level>4</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>com.sap.sailing.www</id>
<level>4</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>com.sap.sailing.xcelsiusadapter</id>
<level>4</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>org.eclipse.equinox.common</id>
<level>2</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>org.eclipse.equinox.simpleconfigurator</id>
<level>2</level>
<autoStart>true</autoStart>
</bundle>
<bundle>
<id>org.eclipse.jetty.osgi.boot</id>
<level>1</level>
<autoStart>true</autoStart>
</bundle>
</bundleStartLevel>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,22 @@
package com.sap.sailing.selenium.test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
import com.sap.sailing.selenium.test.core.Managed;
import com.sap.sailing.selenium.test.core.Selenium;
import com.sap.sailing.selenium.test.core.TestEnvironment;
@RunWith(Selenium.class)
public abstract class AbstractSeleniumTest {
@Managed
protected TestEnvironment environment;
protected String getContextRoot() {
return this.environment.getContextRoot();
}
protected WebDriver getWebDriver() {
return this.environment.getWebDriver();
}
}
@@ -0,0 +1,61 @@
package com.sap.sailing.selenium.test.adminconsole;
import static org.junit.Assert.*;
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 {
@Test
public void test() {
WebDriver driver = getWebDriver();
driver.get(getContextRoot() + "gwt/AdminConsole.html");
assertEquals("Unexpected page title", "SAP Sailing Analytics Administration Console", driver.getTitle());
WebElement tracTracTab = driver.findElement(By.xpath("//div[@class='gwt-TabBarItem' and @role='tab']/div[text()='TracTrac Events']/.."));
tracTracTab.click();
FluentWait<WebDriver> wait = new FluentWait<>(driver);
wait.withTimeout(30, TimeUnit.SECONDS);
wait.pollingEvery(5, TimeUnit.SECONDS);
wait.ignoring(NoSuchElementException.class);
WebElement urlField = wait.until(new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("//div[@class='gwt-Label' and text() = 'JSON URL:']/../../td/input"));
}
});
urlField.clear();
urlField.sendKeys("http://germanmaster.traclive.dk/events/event_20120615_KielerWoch/jsonservice.php");
WebElement listRacesButton = driver.findElement(By.xpath("//button[@class='gwt-Button' and text() = 'List Races']"));
listRacesButton.click();
// wait.withTimeout(5, TimeUnit.MINUTES);
// wait.pollingEvery(10, TimeUnit.SECONDS);
// List<WebElement> trackableRaces = wait.until(new Function<WebDriver, List<WebElement>>() {
// @Override
// public List<WebElement> apply(WebDriver driver) {
// List<WebElement> elements = driver.findElements(By.xpath("//th[text() = 'Event']/../../../tbody/tr"));
// return elements.size() >= 90 ? elements : null;
// }
// });
//
// assertTrue("No trackable races found", trackableRaces.size() > 0);
}
}
@@ -0,0 +1,13 @@
package com.sap.sailing.selenium.test.core;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Managed {
}
@@ -0,0 +1,170 @@
package com.sap.sailing.selenium.test.core;
import java.lang.reflect.Constructor;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.ParentRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.FrameworkField;
import org.junit.runners.model.TestClass;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.sap.sailing.selenium.test.core.TestEnvironmentConfiguration.DriverDefenition;
import com.sap.sailing.selenium.test.core.impl.TestEnvironmentImpl;
public class Selenium extends ParentRunner<Runner> {
private final List<Runner> children;
public Selenium(Class<?> klass) throws InitializationError {
super(klass);
this.children = new LinkedList<>();
initializeRunners();
}
@Override
protected List<Runner> getChildren() {
return this.children;
}
@Override
protected Description describeChild(Runner child) {
// TODO: Provide a better description (including the context root and the driver defenition)
return child.getDescription();
}
@Override
protected void runChild(Runner child, RunNotifier notifier) {
child.run(notifier);
}
@Override
protected void collectInitializationErrors(java.util.List<java.lang.Throwable> errors) {
super.collectInitializationErrors(errors);
// QUESTION: Do we need addional checks here?
}
private void initializeRunners() throws InitializationError {
try {
TestEnvironmentConfiguration configuration = TestEnvironmentConfiguration.getInstance();
String contextRoot = configuration.getContextRoot();
Map<String, String> systemProperties = configuration.getSystemProperties();
for(Entry<String, String> property : systemProperties.entrySet()) {
System.setProperty(property.getKey(), property.getValue());
}
TestClass test = getTestClass();
for(DriverDefenition defenition : configuration.getDriverDefenitions()) {
this.children.add(new SeleniumJUnit4ClassRunner(test.getJavaClass(), contextRoot, defenition));
}
} catch (Exception exception) {
throw new InitializationError(exception);
}
}
private class SeleniumJUnit4ClassRunner extends BlockJUnit4ClassRunner {
private String root;
private DriverDefenition defenition;
private TestEnvironmentImpl environment;
public SeleniumJUnit4ClassRunner(Class<?> klass, String root, DriverDefenition defenition) throws InitializationError {
super(klass);
this.root = root;
this.defenition = defenition;
}
/**
* Create the test object and inject Selenium server or web driver into
* fields that were annotated with {@code annotationType}.
*
* @return The test object.
* @throws Exception
* If there was an error creating the test object.
*/
@Override
protected Object createTest() throws Exception {
final Object test = super.createTest();
final TestClass testClass = getTestClass();
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();
}
}
@Override
protected void collectInitializationErrors(java.util.List<java.lang.Throwable> errors) {
super.collectInitializationErrors(errors);
// QUESTION: Do we need addional checks here?
}
private TestEnvironmentImpl createTestEnvironment() throws Exception {
try {
String driverClassname = this.defenition.getDriver();
Map<String, String> capabilityDefenitions = this.defenition.getCapabilities();
Class<WebDriver> clazz = (Class<WebDriver>) Class.forName(driverClassname);
Capabilities capabilities = new DesiredCapabilities(capabilityDefenitions);
Constructor<WebDriver> constructor = clazz.getConstructor(Capabilities.class);
return new TestEnvironmentImpl(constructor.newInstance(capabilities), this.root);
} catch(Exception exception) {
throw exception;
}
}
}
}
@@ -0,0 +1,9 @@
package com.sap.sailing.selenium.test.core;
import org.openqa.selenium.WebDriver;
public interface TestEnvironment {
public WebDriver getWebDriver();
public String getContextRoot();
}
@@ -0,0 +1,198 @@
package com.sap.sailing.selenium.test.core;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class TestEnvironmentConfiguration {
protected static class DriverDefenition {
private String driver;
private Map<String, String> capabilities;
public DriverDefenition(String driver, Map<String, String> capabilities) {
this.driver = driver;
this.capabilities = capabilities;
}
public String getDriver() {
return this.driver;
}
public Map<String, String> getCapabilities() {
return this.capabilities;
}
}
public static final String TEST_ENVIRONMENT_CONFIGURATION = "selenium.test.environment.configuration";
private static final String TEST_ENVIRONMENT_SCHEMA = "test-environment-configuration.xsd";
private static final String NAMESPACE_URI = "http://www.sapsailing.com/test-environment";
private static final String CONTEXT_ROOT = "context-root";
private static final String SYSTEM_PROPERTIES = "system-properties";
private static final String SYSTEM_PROPERTY = "system-property";
private static final String DRIVER_DEFENITION = "driver-defenition";
private static final String DRIVER_CLASS = "class";
private static final String DRIVER_CAPABILITIES = "capabilities";
private static final String DRIVER_CAPABILITY = "capability";
private static final String PARAMETER_NAME = "name";
private static final String PARAMETER_VALUE = "value";
private static TestEnvironmentConfiguration instance;
public static TestEnvironmentConfiguration getInstance() {
if(instance == null) {
try {
instance = createTestEnvironmentConfiguration();
} catch(Exception exception) {
throw new RuntimeException(exception);
}
}
return instance;
}
private static synchronized TestEnvironmentConfiguration createTestEnvironmentConfiguration() throws
ParserConfigurationException, SAXException, IOException {
if(instance != null)
return instance;
Document document = readTestConfiguration();
Element testEnvironmentNode = document.getDocumentElement();
testEnvironmentNode.normalize();
String contextRoot = XMLHelper.getContentTextNS(testEnvironmentNode, CONTEXT_ROOT, NAMESPACE_URI);
Map<String, String> systemProperties = createSystemProperties(testEnvironmentNode);
List<DriverDefenition> driverDefenitions = createDriverDefenitions(testEnvironmentNode);
return new TestEnvironmentConfiguration(contextRoot, systemProperties, driverDefenitions);
}
private static synchronized Document readTestConfiguration() throws ParserConfigurationException,
SAXException, IOException {
String path = System.getProperty(TEST_ENVIRONMENT_CONFIGURATION);
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new StreamSource(TEST_ENVIRONMENT_SCHEMA));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setValidating(true);
builderFactory.setNamespaceAware(true);
builderFactory.setSchema(schema);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
InputSource source = new InputSource(new FileInputStream(path));
return builder.parse(source);
}
private static Map<String, String> createSystemProperties(Element testEnvironmentNode) {
Element systemPropertiesNode = XMLHelper.getElementNS(testEnvironmentNode, SYSTEM_PROPERTIES, NAMESPACE_URI);
if(systemPropertiesNode == null)
return Collections.EMPTY_MAP;
Map<String, String> properties = new HashMap<>();
List<Element> systemPropertyNodes = XMLHelper.getElementsNS(systemPropertiesNode, SYSTEM_PROPERTY,
NAMESPACE_URI);
for(Element systemPropertyNode : systemPropertyNodes) {
String propertyName = XMLHelper.getContentTextNS(systemPropertyNode, PARAMETER_NAME, NAMESPACE_URI);
String propertyValue = XMLHelper.getContentTextNS(systemPropertyNode, PARAMETER_VALUE, NAMESPACE_URI);
properties.put(propertyName, propertyValue);
}
return properties;
}
private static List<DriverDefenition> createDriverDefenitions(Element testEnvironmentNode) {
List<DriverDefenition> defenitions = new LinkedList<>();
List<Element> driverDefenitionNodes = XMLHelper.getElementsNS(testEnvironmentNode, DRIVER_DEFENITION,
NAMESPACE_URI);
for(Element driverDefenitionNode : driverDefenitionNodes) {
defenitions.add(createDriverDefenition(driverDefenitionNode));
}
return defenitions;
}
private static DriverDefenition createDriverDefenition(Element driverDefenitionNode) {
String driverClass = XMLHelper.getAttributeValueNS(driverDefenitionNode, DRIVER_CLASS, null);;
Element capabilitiesNode = XMLHelper.getElementNS(driverDefenitionNode, DRIVER_CAPABILITIES, NAMESPACE_URI);
if(capabilitiesNode == null)
return new DriverDefenition(driverClass, Collections.EMPTY_MAP);
Map<String, String> capabilities = new HashMap<>();
for(Element capabilityNode : XMLHelper.getElementsNS(capabilitiesNode, DRIVER_CAPABILITY, NAMESPACE_URI)) {
String capabilityName = XMLHelper.getContentTextNS(capabilityNode, PARAMETER_NAME, NAMESPACE_URI);
String capabilityValue = XMLHelper.getContentTextNS(capabilityNode, PARAMETER_VALUE, NAMESPACE_URI);
capabilities.put(capabilityName, capabilityValue);
}
return new DriverDefenition(driverClass, capabilities);
}
private String root;
private Map<String, String> properties;
private List<DriverDefenition> defenitions;
private TestEnvironmentConfiguration(String root, Map<String, String> properties, List<DriverDefenition> defenitions) {
this.root = root;
this.properties = properties;
this.defenitions = defenitions;
}
public String getContextRoot() {
return this.root;
}
public Map<String, String> getSystemProperties() {
return this.properties;
}
public List<DriverDefenition> getDriverDefenitions() {
return this.defenitions;
}
}
@@ -0,0 +1,95 @@
package com.sap.sailing.selenium.test.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class XMLHelper {
public static String getAttributeValueNS(Element element, String name, String uri) {
return getAttributeValueNS(element, name, uri, null);
}
public static String getAttributeValueNS(Element element, String name, String uri, String defaultValue) {
Attr attribute = element.getAttributeNodeNS(uri, name);
if(attribute != null)
return attribute.getValue();
return defaultValue;
}
public static String getContentText(Element element) {
if(element == null)
return null;
return element.getTextContent();
}
public static String getContentTextNS(Element element, String name, String uri) {
return getContentTextNS(element, name, uri, null);
}
public static String getContentTextNS(Element element, String name, String uri, String defaultValue) {
Element child = getElementNS(element, name, uri);
if(child != null)
return getContentText(child);
return defaultValue;
}
public static Element getElementNS(Element element, String name, String uri) {
if(element == null || !element.hasChildNodes())
return null;
for(Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
if(child.getNodeType() != Node.ELEMENT_NODE)
continue;
if(matches(child, name, uri))
return (Element) child;
}
return null;
}
public static List<Element> getElements(Element element, String name) {
return getElementsNS(element, name, null);
}
public static List<Element> getElementsNS(Element element, String name, String uri) {
if(element == null || !element.hasChildNodes())
return Collections.emptyList();
List<Element> elements = new ArrayList<>();
for(Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
if(child.getNodeType() == Node.ELEMENT_NODE) {
if(matches(child, name, uri))
elements.add((Element) child);
}
}
return elements;
}
private static boolean matches(Node node, String name, String uri) {
String tagName = node.getLocalName();
String namespaceUri = node.getNamespaceURI();
if(!name.equals(tagName))
return false;
if(uri == null)
return true;
if(!uri.equals(namespaceUri))
return false;
return true;
}
}
@@ -0,0 +1,31 @@
package com.sap.sailing.selenium.test.core.impl;
import org.openqa.selenium.WebDriver;
import com.sap.sailing.selenium.test.core.TestEnvironment;
public class TestEnvironmentImpl implements TestEnvironment {
private WebDriver driver;
private String root;
public TestEnvironmentImpl(WebDriver driver, String root) {
this.driver = driver;
this.root = root;
}
@Override
public WebDriver getWebDriver() {
return this.driver;
}
@Override
public String getContextRoot() {
return this.root;
}
public void close() {
this.driver.quit();
this.driver = null;
this.root = null;
}
}
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:cfg="http://www.sapsailing.com/test-environment"
targetNamespace="http://www.sapsailing.com/test-environment" elementFormDefault="qualified">
<xsd:element name="test-environment" type="cfg:test-environment" />
<xsd:complexType name="test-environment">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="context-root" type="xsd:string" minOccurs="1" maxOccurs="1" />
<xsd:element name="system-properties" type="cfg:system-properties" minOccurs="0" maxOccurs="1" />
<xsd:element name="driver-defenition" type="cfg:driver-defenition" minOccurs="1" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="system-properties">
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="system-property" type="cfg:parameter" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="driver-defenition">
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="capabilities" type="cfg:capabilities" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="class" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="capabilities">
<xsd:annotation>
<xsd:documentation>
See http://code.google.com/p/selenium/wiki/DesiredCapabilities
</xsd:documentation>
</xsd:annotation>
<xsd:sequence minOccurs="1" maxOccurs="unbounded">
<xsd:element name="capability" type="cfg:parameter" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="parameter">
<xsd:sequence minOccurs="1" maxOccurs="1">
<xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" />
<xsd:element name="value" type="xsd:string" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>