Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
70 changed files
with
3,250 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
# Silk AppDriver # | ||
|
||
**Silk AppDriver** is an implementation of the [W3C WebDriver protocol](https://www.w3.org/TR/webdriver/) for native (Windows) and mobile (Android and iOS) applications, built on top of [Silk Test](https://www.microfocus.com/de-de/products/silk-portfolio/silk-test/). The purpose of this project is to enable users of Silk Test to write tests for all kinds of applications using the WebDriver API in addition to the existing Silk Test APIs. | ||
|
||
## Prerequisites ## | ||
|
||
* Silk Test 18.0 has to be installed with a valid license. If you don't have Silk Test, download the evaluation version from [https://www.microfocus.com/de-de/products/silk-portfolio/silk-test/trial/](https://www.microfocus.com/de-de/products/silk-portfolio/silk-test/trial/) | ||
* Java (at least 1.8) has to be installed | ||
|
||
## Running ## | ||
|
||
* Download the latest **Silk AppDriver** release from [GitHub](https://github.com/MicroFocus/SilkAppDriver/releases) | ||
* Run the **Silk AppDriver** server from the command line: `java -jar silk-appdriver.jar` | ||
* Run your tests against a *RemoteWebDriver* pointed to that server (http://localhost:8080 by default) | ||
* To use a different port than 8080 run **Silk AppDriver** with the `server.port` system property, for example `java -Dserver.port=8123 -jar silk-appdriver.jar` | ||
|
||
## Examples ## | ||
|
||
Here's a minimal example written in Python that automates notepad.exe using Silk AppDriver: | ||
|
||
```python | ||
from selenium import webdriver | ||
|
||
driver = webdriver.Remote( | ||
command_executor='http://127.0.0.1:8080', | ||
desired_capabilities={'app': '%WINDIR%\\notepad.exe'}) | ||
|
||
textfield = driver.find_element_by_xpath("//TextField") | ||
textfield.clear() | ||
textfield.send_keys("hello from python!") | ||
|
||
driver.find_element_by_xpath("//Menu[@caption='File']").click() | ||
driver.find_element_by_xpath("//MenuItem[@caption='Exit']").click() | ||
driver.find_element_by_xpath("//PushButton[@caption=\"Don't Save\"]").click() | ||
|
||
driver.quit() | ||
``` | ||
|
||
![](resources/example.gif) | ||
|
||
Further examples can be found here: | ||
* Java (notepad.exe): [NotepadDemoTest.java](samples/java/appdriver-tests/src/test/java/com/microfocus/silk/appdriver/tests/NotepadDemoTest.java) | ||
* Java (mobile app on Android): [MobileTests.java](samples/java/appdriver-tests/src/test/java/com/microfocus/silk/appdriver/tests/MobileTests.java) | ||
* Python (notepad.exe): [notepad.py](samples/python/notepad.py) | ||
* JavaScript (notepad.exe): [notepad.js](samples/javascript/notepad.js) | ||
|
||
## Building ## | ||
|
||
To build **Silk AppDriver** on the command line: | ||
* Make sure you have silktest.jtf:18.0 in your local maven repository (See "Adding the JTF to your local Maven repository" in our ["Embracing Open Source"](https://community.microfocus.com/borland/test/silk_test/b/weblog/posts/embracing-open-source-maven-and-jenkins-2) blog post.) | ||
* Build the project with maven (`mvn clean install`) | ||
* Run the **Silk AppDriver** server from the command line: `java -jar target/silk-appdriver.jar` | ||
|
||
To build Silk WebDriver in the IDE: | ||
* Import the **Silk AppDriver** project into Eclipse (at least 4.6.0) and build with maven. | ||
|
||
## Architecture ## | ||
|
||
![](resources/architecture.png) | ||
|
||
## Noteworthy ## | ||
The controller stub was auto-generated based on the ["List of Endpoints"](https://www.w3.org/TR/webdriver/#list-of-endpoints) in the WebDriver standard using a simple Silk4J script. That can be found here: [appdriver-generate](src/silk.appdriver.generate/src/Generate.java) | ||
|
||
## Current status ## | ||
|
||
**Silk AppDriver** is still in an early stage and needs your help and contributions to get better! | ||
|
||
### Locator strategies ### | ||
|
||
Only *xpath* is currently supported as a locator strategy. Ony "Silk Test xpath" locators will work. | ||
|
||
### API ### | ||
|
||
The following table lists all methods listed in the [W3C spec](https://www.w3.org/TR/webdriver/) and the current status of the implementation in **Silk AppDriver**. | ||
|
||
| Command | Status | Comment | | ||
|----------|---------|---------| | ||
| [New Session](https://www.w3.org/TR/webdriver/#dfn-new-session) | Done | | | ||
| [Delete Session](https://www.w3.org/TR/webdriver/#dfn-delete-session) | Done | | | ||
| [Status](https://www.w3.org/TR/webdriver/#dfn-status) | Done | | | ||
| [Get Timeouts](https://www.w3.org/TR/webdriver/#dfn-get-timeouts) | TODO | | | ||
| [Set Timeouts](https://www.w3.org/TR/webdriver/#dfn-set-timeouts) | TODO | | | ||
| [Go](https://www.w3.org/TR/webdriver/#dfn-go) | Done | Not supported (yields "unknown command") | | ||
| [Get Current URL](https://www.w3.org/TR/webdriver/#dfn-get-current-url) | Done | Not supported (yields "unknown command") | | ||
| [Back](https://www.w3.org/TR/webdriver/#dfn-back) | Done | Not supported (yields "unknown command") | | ||
| [Forward](https://www.w3.org/TR/webdriver/#dfn-forward) | Done | Not supported (yields "unknown command") | | ||
| [Refresh](https://www.w3.org/TR/webdriver/#dfn-refresh) | Done | Not supported (yields "unknown command") | | ||
| [Get Title](https://www.w3.org/TR/webdriver/#dfn-get-title) | Done | | | ||
| [Get Window Handle](https://www.w3.org/TR/webdriver/#dfn-get-window-handle) | Done | | | ||
| [Close Window](https://www.w3.org/TR/webdriver/#dfn-close-window) | Donw | | | ||
| [Switch To Window](https://www.w3.org/TR/webdriver/#dfn-switch-to-window) | TODO | | | ||
| [Get Window Handles](https://www.w3.org/TR/webdriver/#dfn-get-window-handles) | Done | | | ||
| [Switch To Frame](https://www.w3.org/TR/webdriver/#dfn-switch-to-frame) | Done | Not supported (yields "unknown command") | | ||
| [Switch To Parent Frame](https://www.w3.org/TR/webdriver/#dfn-switch-to-parent-frame) | Done | Not supported (yields "unknown command") | | ||
| [Get Window Rect](https://www.w3.org/TR/webdriver/#dfn-get-window-rect) | Done | | | ||
| [Set Window Rect](https://www.w3.org/TR/webdriver/#dfn-set-window-rect) | Done | | | ||
| [Maximize Window](https://www.w3.org/TR/webdriver/#dfn-maximize-window) | Done | | | ||
| [Minimize Window](https://www.w3.org/TR/webdriver/#dfn-minimize-window) | Done | | | ||
| [Fullscreen Window](https://www.w3.org/TR/webdriver/#dfn-fullscreen-window) | Done | | | ||
| [Get Active Element](https://www.w3.org/TR/webdriver/#dfn-get-active-element) | TODO | | | ||
| [Find Element](https://www.w3.org/TR/webdriver/#dfn-find-element) | Done | | | ||
| [Find Elements](https://www.w3.org/TR/webdriver/#dfn-find-elements) | Done | | | ||
| [Find Element From Element](https://www.w3.org/TR/webdriver/#dfn-find-element-from-element) | Done | | | ||
| [Find Elements From Element](https://www.w3.org/TR/webdriver/#dfn-find-elements-from-element) | Done | | | ||
| [Is Element Selected](https://www.w3.org/TR/webdriver/#dfn-is-element-selected) | TODO | | | ||
| [Get Element Attribute](https://www.w3.org/TR/webdriver/#dfn-get-element-attribute) | TODO | | | ||
| [Get Element Property](https://www.w3.org/TR/webdriver/#dfn-get-element-property) | TODO | | | ||
| [Get Element CSS Value](https://www.w3.org/TR/webdriver/#dfn-get-element-css-value) | Done | Not supported (yields "unknown command") | | ||
| [Get Element Text](https://www.w3.org/TR/webdriver/#dfn-get-element-text) | Done | | | ||
| [Get Element Tag Name](https://www.w3.org/TR/webdriver/#dfn-get-element-tag-name) | Done | Yields the class name | | ||
| [Get Element Rect](https://www.w3.org/TR/webdriver/#dfn-get-element-rect) | Done | | | ||
| [Is Element Enabled](https://www.w3.org/TR/webdriver/#dfn-is-element-enabled) | TODO | | | ||
| [Element Click](https://www.w3.org/TR/webdriver/#dfn-element-click) | Done | | | ||
| [Element Clear](https://www.w3.org/TR/webdriver/#dfn-element-clear) | Done | | | ||
| [Element Send Keys](https://www.w3.org/TR/webdriver/#dfn-element-send-keys) | Partly done | Missing: Handling of special keys | | ||
| [Get Page Source](https://www.w3.org/TR/webdriver/#dfn-get-page-source) | Done | Not supported (yields "unknown command") | | ||
| [Execute Script](https://www.w3.org/TR/webdriver/#dfn-execute-script) | Done | Not supported (yields "unknown command") | | ||
| [Execute Async Script](https://www.w3.org/TR/webdriver/#dfn-execute-async-script) | Done | Not supported (yields "unknown command") | | ||
| [Get All Cookies](https://www.w3.org/TR/webdriver/#dfn-get-all-cookies) | Done | Not supported (yields "unknown command") | | ||
| [Get Named Cookie](https://www.w3.org/TR/webdriver/#dfn-get-named-cookie) | Done | Not supported (yields "unknown command") | | ||
| [Add Cookie](https://www.w3.org/TR/webdriver/#dfn-add-cookie) | Done | Not supported (yields "unknown command") | | ||
| [Delete Cookie](https://www.w3.org/TR/webdriver/#dfn-delete-cookie) | Done | Not supported (yields "unknown command") | | ||
| [Delete All Cookies](https://www.w3.org/TR/webdriver/#dfn-delete-all-cookies) | Done | Not supported (yields "unknown command") | | ||
| [Perform Actions](https://www.w3.org/TR/webdriver/#dfn-perform-implementation-specific-action-dispatch-steps) | TODO | | | ||
| [Release Actions](https://www.w3.org/TR/webdriver/#dfn-release-actions) | TODO | | | ||
| [Dismiss Alert](https://www.w3.org/TR/webdriver/#dfn-dismiss-alert) | TODO | | | ||
| [Accept Alert](https://www.w3.org/TR/webdriver/#dfn-accept-alert) | TODO | | | ||
| [Get Alert Text](https://www.w3.org/TR/webdriver/#dfn-get-alert-text) | TODO | | | ||
| [Send Alert Text](https://www.w3.org/TR/webdriver/#dfn-send-alert-text) | TODO | | | ||
| [Take Screenshot](https://www.w3.org/TR/webdriver/#dfn-take-screenshot) | TODO | | | ||
| [Take Element Screenshot](https://www.w3.org/TR/webdriver/#dfn-take-element-screenshot) | TODO | | | ||
|
||
### TODOs ### | ||
|
||
The biggest TODOs currently are: | ||
|
||
* Add more tests! | ||
* Add tests in other Selenium languages! | ||
* Implement the ability to specify more of the Silk Test BaseState options (through capabilities?) | ||
* Implement attribute/property retrieval. Do we need to distinguish between the two? | ||
* Implement handling special keys in `sendKeys` (map to Silk Test keys!) | ||
* Implement screenshot API | ||
* Implement customizable timeouts and other options | ||
* Implement window handling and switching between multiple windows | ||
* Add a possibility to get TrueLog files. Maybe we can use `executeScript` with a custom command to start/stop TrueLog? | ||
* Implement other locator strategies (by Id, by className, ... should be easy to map to XPath) | ||
* Implement alert handling | ||
* Implement action API | ||
* Add support for mobile and web apps | ||
* The Java client bindings (among others) support a [Select](https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/Select.html) helper method. Internally this relies on a couple of specifics (tag name has to be "select", children have to be "options", ...). Can we make that work with our combo boxes as well? | ||
|
||
## License | ||
Code provided in this repository is licensed under the [Apache 2.0](LICENSE). | ||
|
||
## Contribution | ||
You want to contribute to **Silk AppDriver**? Great! | ||
|
||
Changes may be contributed after signing the [Micro Focus Individual Contributor License Agreement 1.0](OpenSourceContributionAgreement1_0.pdf). | ||
Signed contributor agreements are to be sent, via PDF, to <licensing@microfocus.com>. | ||
You will be notified via email when the agreement has been accepted by Micro Focus. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> | ||
<attributes> | ||
<attribute name="optional" value="true"/> | ||
<attribute name="maven.pomderived" value="true"/> | ||
</attributes> | ||
</classpathentry> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"> | ||
<attributes> | ||
<attribute name="maven.pomderived" value="true"/> | ||
</attributes> | ||
</classpathentry> | ||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> | ||
<attributes> | ||
<attribute name="maven.pomderived" value="true"/> | ||
</attributes> | ||
</classpathentry> | ||
<classpathentry kind="output" path="target/classes"/> | ||
</classpath> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
bin/ | ||
target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>appdriver-tests</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.m2e.core.maven2Builder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||
</natures> | ||
</projectDescription> |
3 changes: 3 additions & 0 deletions
3
samples/java/appdriver-tests/.settings/org.eclipse.core.resources.prefs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
eclipse.preferences.version=1 | ||
encoding//src/test/java=UTF-8 | ||
encoding/<project>=UTF-8 |
13 changes: 13 additions & 0 deletions
13
samples/java/appdriver-tests/.settings/org.eclipse.jdt.core.prefs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
org.eclipse.jdt.core.compiler.compliance=1.8 | ||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||
org.eclipse.jdt.core.compiler.source=1.8 |
4 changes: 4 additions & 0 deletions
4
samples/java/appdriver-tests/.settings/org.eclipse.m2e.core.prefs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
activeProfiles= | ||
eclipse.preferences.version=1 | ||
resolveWorkspaceProjects=true | ||
version=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.microfocus.silk</groupId> | ||
<artifactId>appdriver-tests</artifactId> | ||
<version>1.0.0</version> | ||
<packaging>jar</packaging> | ||
|
||
<name>appdriver-tests</name> | ||
<url>https://github.com/MicroFocus/SilkAppDriver</url> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>1.8</maven.compiler.source> | ||
<maven.compiler.target>1.8</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>4.4</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.seleniumhq.selenium</groupId> | ||
<artifactId>selenium-java</artifactId> | ||
<version>LATEST</version> | ||
</dependency> | ||
</dependencies> | ||
<organization> | ||
<name>Micro Focus</name> | ||
<url>www.microfocus.com</url> | ||
</organization> | ||
</project> |
97 changes: 97 additions & 0 deletions
97
...ava/appdriver-tests/src/test/java/com/microfocus/silk/appdriver/tests/ExceptionTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package com.microfocus.silk.appdriver.tests; | ||
|
||
import java.net.URL; | ||
|
||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Ignore; | ||
import org.junit.Test; | ||
import org.openqa.selenium.By; | ||
import org.openqa.selenium.NoSuchElementException; | ||
import org.openqa.selenium.StaleElementReferenceException; | ||
import org.openqa.selenium.UnsupportedCommandException; | ||
import org.openqa.selenium.WebDriver; | ||
import org.openqa.selenium.WebElement; | ||
import org.openqa.selenium.remote.DesiredCapabilities; | ||
import org.openqa.selenium.remote.RemoteWebDriver; | ||
|
||
public class ExceptionTests { | ||
private static final String APP = "%WINDIR%\\notepad.exe"; | ||
|
||
private WebDriver driver; | ||
|
||
@Before | ||
public void startApp() throws Exception { | ||
DesiredCapabilities capabilities = new DesiredCapabilities(); | ||
capabilities.setCapability("app", APP); | ||
|
||
driver = new RemoteWebDriver(new URL("http://localhost:8080"), capabilities); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testGoNotSupported() { | ||
driver.navigate().to("http://www.google.at"); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testGetCurrentUrlNotSupported() { | ||
driver.getCurrentUrl(); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testBackNotSupported() { | ||
driver.navigate().back(); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testForwardNotSupported() { | ||
driver.navigate().forward(); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testRefreshNotSupported() { | ||
driver.navigate().refresh(); | ||
} | ||
|
||
@Ignore // Ignored for now - delegates to executeScript currently (Selenium | ||
// 3.6) which it probably shouldn't | ||
@Test(expected = UnsupportedCommandException.class) | ||
public void testgetPageSourceNotSupported() { | ||
driver.getPageSource(); | ||
} | ||
|
||
@Test(expected = NoSuchElementException.class) | ||
public void testNoSuchElementException() throws Exception { | ||
driver.findElement(By.xpath("//Window[@caption='bla']")); | ||
} | ||
|
||
@Test(expected = UnsupportedCommandException.class) | ||
public void testFindByCssNotSupported() { | ||
driver.findElement(By.cssSelector("test")); | ||
} | ||
|
||
@Test(expected = StaleElementReferenceException.class) | ||
public void testStaleElementReferenceException() { | ||
driver.findElement(By.xpath("//Menu[@caption='Format']")).click(); | ||
driver.findElement(By.xpath("//MenuItem[@caption='Font']")).click(); | ||
|
||
WebElement ok = driver.findElement(By.xpath("//PushButton[@caption='OK']")); | ||
|
||
ok.click(); | ||
|
||
ok.click(); // Dialog is disposed, button isn't there any more, | ||
// StaleElementReferenceException should be raised | ||
} | ||
|
||
@After | ||
public void closeApp() { | ||
WebElement fileMenu = driver.findElement(By.xpath("//Menu[@caption='File']")); | ||
fileMenu.click(); | ||
|
||
WebElement exit = driver.findElement(By.xpath("//MenuItem[@caption='Exit']")); | ||
exit.click(); | ||
|
||
driver.quit(); | ||
} | ||
|
||
} |
Oops, something went wrong.