diff --git a/.gitignore b/.gitignore
index 2e6268a4..949283d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ apidocs/*
bin/*
build/*
npm-debug.log
-.vscode
\ No newline at end of file
+.vscode
+**/reports/*
\ No newline at end of file
diff --git a/e2e/md/assert.md b/e2e/md/assert.md
new file mode 100644
index 00000000..4528f0d5
--- /dev/null
+++ b/e2e/md/assert.md
@@ -0,0 +1,4 @@
+### assert
+- [x] equal
+- [x] notEqual
+- [x] fail
\ No newline at end of file
diff --git a/e2e/md/date.md b/e2e/md/date.md
new file mode 100644
index 00000000..6ea2fd6c
--- /dev/null
+++ b/e2e/md/date.md
@@ -0,0 +1,3 @@
+### date
+- [x] now
+- [x] fromNow
diff --git a/e2e/md/db.md b/e2e/md/db.md
new file mode 100644
index 00000000..f2545dcf
--- /dev/null
+++ b/e2e/md/db.md
@@ -0,0 +1,5 @@
+### db
+- [x] setConnectionString
+- [x] getScalar
+- [x] executeQuery
+- [x] executeNonQuery
\ No newline at end of file
diff --git a/e2e/md/email.md b/e2e/md/email.md
new file mode 100644
index 00000000..aa4ca303
--- /dev/null
+++ b/e2e/md/email.md
@@ -0,0 +1,3 @@
+### email
+- [x] init
+- [x] getLastEmail
\ No newline at end of file
diff --git a/e2e/md/eyes.md b/e2e/md/eyes.md
new file mode 100644
index 00000000..6ad92319
--- /dev/null
+++ b/e2e/md/eyes.md
@@ -0,0 +1,5 @@
+### eyes
+- [ ] init
+- [ ] dispose
+- [ ] check
+- [ ] checkWindow
\ No newline at end of file
diff --git a/e2e/md/http.md b/e2e/md/http.md
new file mode 100644
index 00000000..1eb25a38
--- /dev/null
+++ b/e2e/md/http.md
@@ -0,0 +1,6 @@
+### http
+- [x] get
+- [x] post
+- [x] put
+- [x] delete
+- [x] getResponseHeaders
\ No newline at end of file
diff --git a/e2e/md/log.md b/e2e/md/log.md
new file mode 100644
index 00000000..5c51f6a6
--- /dev/null
+++ b/e2e/md/log.md
@@ -0,0 +1,5 @@
+### log
+- [x] info
+- [x] error
+- [x] debug
+- [x] warn
\ No newline at end of file
diff --git a/e2e/md/mob.android.mob.md b/e2e/md/mob.android.mob.md
new file mode 100644
index 00000000..47a9a53d
--- /dev/null
+++ b/e2e/md/mob.android.mob.md
@@ -0,0 +1,66 @@
+### dependencies
+- Android Studio
+- Virtual Device
+- appium --allow-insecure chromedriver_autodownload
+
+### mob.android.mob
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] alertAccept
+- [x] alertDismiss
+- [x] assertText
+- :x: assertValue
+- [x] back
+- [x] clear
+- [x] click
+- [x] clickLong
+- [x] clickMultipleTimes
+- [x] closeApp
+- [x] dragAndDrop
+- [x] enableNetwork
+- [x] findElement
+- [x] findElements
+- [x] getAlertText
+- [x] getAppiumLogs
+- [x] getCurrentActivity
+- [x] getCurrentPackage
+- :x: getBrowserLogs
+- [x] getDeviceLogs
+- [x] getDeviceTime
+- [x] getLocation
+- [x] getSource
+- [x] getText
+- :x: getValue
+- [x] hideKeyboard
+- [x] installApp
+- [x] isAppInstalled
+- [x] isCheckable
+- [x] isChecked
+- [x] isClickable
+- [x] isExist
+- [x] isSelected
+- [x] isVisible
+- [x] isWebViewContext
+- [x] launchApp
+- [x] pause
+- [x] removeApp
+- [x] resetApp
+- [x] scrollIntoElement
+- [x] sendKeys
+- [x] setContext
+- [x] setNativeContext
+- [x] setTimeout
+- [x] setWebViewContext
+- :x: smsClickLink
+- :x: smsGetText
+- [x] swipe
+- [x] swipeElement
+- [x] swipeScreen
+- [x] takeScreenshot
+- [x] tap
+- [x] type
+- :x: unlockPattern
+- [x] waitForExist
+- [x] waitForVisible
diff --git a/e2e/md/mob.android.web.md b/e2e/md/mob.android.web.md
new file mode 100644
index 00000000..142faa42
--- /dev/null
+++ b/e2e/md/mob.android.web.md
@@ -0,0 +1,50 @@
+### dependencies
+- Android Studio
+- Virtual Device
+- appium --allow-insecure chromedriver_autodownload
+- selenium
+
+### mob.android.web
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] alertAccept
+- [x] alertDismiss
+- [x] assertText
+- [x] assertTitle
+- [x] assertValue
+- [x] back
+- [x] clear
+- [x] click
+- [x] clickHidden
+- [x] clickLong
+- [x] clickMultipleTimes
+- [x] execute
+- [x] findElement
+- [x] findElements
+- [x] getAlertText
+- :x: getAppiumLogs
+- [x] getDeviceLogs
+- [x] getBrowserLogs
+- [x] getLocation
+- [x] getSource
+- [x] getText
+- [x] getValue
+- [x] hideKeyboard
+- [x] isExist
+- [x] isVisible
+- [x] isWebViewContext
+- [x] open
+- [x] pause
+- [x] scrollIntoView
+- [x] selectFrame
+- [x] sendKeys
+- [x] setContext
+- [x] setNativeContext
+- [x] setTimeout
+- [x] setWebViewContext
+- [x] takeScreenshot
+- [x] type
+- [x] waitForExist
+- [x] waitForVisible
\ No newline at end of file
diff --git a/e2e/md/mob.ios.mob.md b/e2e/md/mob.ios.mob.md
new file mode 100644
index 00000000..3b9b3254
--- /dev/null
+++ b/e2e/md/mob.ios.mob.md
@@ -0,0 +1,60 @@
+### dependencies
+- Xcode
+- Virtual Device
+- appium
+- carthage
+
+### Env variables
+- udid
+- deviceName
+- platformVersion
+
+### mob.ios.mob
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] alertAccept
+- [x] alertDismiss
+- [x] assertText
+- [x] assertValue
+- [x] clear
+- [x] click
+- [x] clickLong
+- [x] clickMultipleTimes
+- [x] closeApp
+- :grey_question: dragAndDrop
+- [x] findElement
+- [x] findElements
+- [x] getAlertText
+- :x: getAppiumLogs
+- :x: getDeviceLogs
+- [x] getDeviceTime
+- [x] getLocation
+- [x] getSource
+- [x] getText
+- [x] getValue
+- [x] installApp
+- [x] isAppInstalled
+- [x] isExist
+- [x] isVisible
+- :grey_question: isWebViewContext
+- [x] launchApp
+- [x] pause
+- [x] removeApp
+- [x] resetApp
+- :x: scrollIntoElement
+- [x] sendKeys
+- [x] setContext
+- [x] setNativeContext
+- [x] setTimeout
+- :grey_question: setWebViewContext
+- :grey_question: shake
+- [x] swipe
+- :x: swipeElement
+- [x] swipeScreen
+- [x] takeScreenshot
+- [x] tap
+- [x] type
+- [x] waitForExist
+- [x] waitForVisible
\ No newline at end of file
diff --git a/e2e/md/mob.ios.web.md b/e2e/md/mob.ios.web.md
new file mode 100644
index 00000000..e939eb16
--- /dev/null
+++ b/e2e/md/mob.ios.web.md
@@ -0,0 +1,55 @@
+### dependencies
+- Xcode
+- Virtual Device
+- appium
+- carthage
+- selenium
+
+### Env variables
+- udid
+- deviceName
+- platformVersion
+
+### mob.ios.web
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] alertAccept
+- [x] alertDismiss
+- [x] assertText
+- [x] assertTitle
+- [x] assertValue
+- :x: back
+- [x] clear
+- [x] click
+- :x: clickHidden
+- :x: clickLong
+- :x: clickMultipleTimes
+- [x] execute
+- [x] findElement
+- [x] findElements
+- [x] getAlertText
+- [x] getAppiumLogs
+- [x] getDeviceLogs
+- [x] getLocation
+- [x] getSource
+- [x] getText
+- [x] getValue
+- [x] hideKeyboard
+- [x] isExist
+- [x] isVisible
+- [x] isWebViewContext
+- [x] open
+- [x] pause
+- [x] scrollIntoView
+- [x] selectFrame
+- :x: sendKeys
+- [x] setContext
+- [x] setNativeContext
+- [x] setTimeout
+- [x] setWebViewContext
+- [x] takeScreenshot
+- [x] type
+- [x] waitForExist
+- [x] waitForVisible
\ No newline at end of file
diff --git a/e2e/md/pdf.md b/e2e/md/pdf.md
new file mode 100644
index 00000000..471551b8
--- /dev/null
+++ b/e2e/md/pdf.md
@@ -0,0 +1,4 @@
+### pdf
+- [x] assert
+- [x] assertNot
+- [x] count
\ No newline at end of file
diff --git a/e2e/md/serial.md b/e2e/md/serial.md
new file mode 100644
index 00000000..c37d725f
--- /dev/null
+++ b/e2e/md/serial.md
@@ -0,0 +1,5 @@
+### serial
+- [x] list
+- [x] open
+- [x] waitForText
+- [x] write
\ No newline at end of file
diff --git a/e2e/md/shell.md b/e2e/md/shell.md
new file mode 100644
index 00000000..44cbccab
--- /dev/null
+++ b/e2e/md/shell.md
@@ -0,0 +1,2 @@
+### shell
+- [x] exec
\ No newline at end of file
diff --git a/e2e/md/soap.md b/e2e/md/soap.md
new file mode 100644
index 00000000..79a69e82
--- /dev/null
+++ b/e2e/md/soap.md
@@ -0,0 +1,6 @@
+### soap
+- :grey_question: authBasic
+- :grey_question: authBearer
+- :grey_question: authNTLM
+- [x] get
+- [x] describe
\ No newline at end of file
diff --git a/e2e/md/twilio.md b/e2e/md/twilio.md
new file mode 100644
index 00000000..844b3931
--- /dev/null
+++ b/e2e/md/twilio.md
@@ -0,0 +1,8 @@
+### Env variables
+- accountSid
+- authToken
+
+### twilio
+- [x] init
+- :grey_question: getLastSms
+- :grey_question: sendSms
\ No newline at end of file
diff --git a/e2e/md/web.md b/e2e/md/web.md
new file mode 100644
index 00000000..88dd4575
--- /dev/null
+++ b/e2e/md/web.md
@@ -0,0 +1,76 @@
+### dependencies
+- selenium
+- chrome
+
+### web
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] alertAccept
+- [x] alertDismiss
+- [x] assertAlert
+- [x] assertExist
+- [x] assertSelectedLabel
+- [x] assertSelectedValue
+- [x] assertText
+- [x] assertTextNotPresent
+- [x] assertTextPresent
+- [x] assertTitle
+- [x] assertValue
+- [x] back
+- [x] clear
+- [x] click
+- [x] clickHidden
+- [x] closeWindow
+- [x] deleteCookies
+- [x] deselect
+- [x] doubleClick
+- [x] dragAndDrop
+- [x] execute
+- :x: fileBrowse
+- [x] findElement
+- [x] findElements
+- [x] getAlertText
+- [x] getAttribute
+- [x] getBrowserLogs
+- [x] getCookies
+- [x] getCssValue
+- [x] getElementCount
+- :x: getHTML
+- [x] getSource
+- [x] getText
+- [x] getTitle
+- [x] getUrl
+- [x] getValue
+- [x] getWindowHandles
+- [x] getXMLPageSource
+- [x] isAlertPresent
+- :x: isChecked
+- [x] isExist
+- [x] isSelected
+- [x] isVisible
+- [x] makeVisible
+- [x] open
+- [x] pause
+- [x] point
+- [x] refresh
+- [x] rightClick
+- [x] scrollToElement
+- [x] select
+- [x] selectFrame
+- [x] selectWindow
+- [x] sendKeys
+- [x] setTimeout
+- [x] setWindowSize
+- [x] getWindowSize
+- [x] takeScreenshot
+- [x] type
+- [x] waitForExist
+- [x] waitForNotExist
+- [x] waitForNotText
+- [x] waitForNotValue
+- [x] waitForText
+- [x] waitForValue
+- [x] waitForVisible
+- [x] waitForWindow
\ No newline at end of file
diff --git a/e2e/md/win.md b/e2e/md/win.md
new file mode 100644
index 00000000..798ae973
--- /dev/null
+++ b/e2e/md/win.md
@@ -0,0 +1,43 @@
+### dependencies
+- Windows
+- appium
+
+### win
+- [x] getCapabilities
+- [x] init
+- [x] dispose
+- [x] transaction
+- [x] assertText
+- [x] assertTitle
+- :x: assertValue
+- :x: back
+- [x] clear
+- [x] click
+- [x] clickLong
+- [x] clickMultipleTimes
+- [x] findElement
+- [x] findElements
+- :x: getAppiumLogs
+- :x: getLocation
+- [x] getSource
+- [x] getText
+- :x: getValue
+- :x: isCheckable
+- :x: isChecked
+- :x: isClickable
+- [x] isExist
+- [x] isSelected
+- [x] isVisible
+- :x: open
+- [x] pause
+- [x] rightClick
+- :x: sendKeys
+- [x] setTimeout
+- [x] takeScreenshot
+- :x: tap
+- [x] type
+- [x] waitForExist
+- [x] waitForVisible
+- :grey_question: getCurrentWindowHandle
+- :grey_question: getWindowHandles
+- :grey_question: selectWindow
\ No newline at end of file
diff --git a/e2e/tests/assert.js b/e2e/tests/assert.js
new file mode 100644
index 00000000..151f2054
--- /dev/null
+++ b/e2e/tests/assert.js
@@ -0,0 +1,44 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/assert/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('assert-module', () => {
+ it('assert correct', async () => {
+ const response = await cliProcess.execute('assert.assertPass.js');
+ shouldPass(response);
+ });
+
+ it('assert not correct', async () => {
+ const response = await cliProcess.execute('assert.assertFail.js');
+ shouldFail(response);
+ });
+
+ it('assertNot correct', async () => {
+ const response = await cliProcess.execute('assert.assertNotPass.js');
+ shouldPass(response);
+ });
+
+ it('assertNot not correct', async () => {
+ const response = await cliProcess.execute('assert.assertNotFail.js');
+ shouldFail(response);
+ });
+
+ it('fail correct', async () => {
+ const response = await cliProcess.execute('assert.failFail.js');
+ shouldFail(response);
+ });
+
+ it('fail correct 2', async () => {
+ const response = await cliProcess.execute('assert.failPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.assertFail.js b/e2e/tests/assert/tests/assert.assertFail.js
new file mode 100644
index 00000000..ae72d0d4
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.assertFail.js
@@ -0,0 +1 @@
+assert.equal(1,2);
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.assertNotFail.js b/e2e/tests/assert/tests/assert.assertNotFail.js
new file mode 100644
index 00000000..2fe798d7
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.assertNotFail.js
@@ -0,0 +1 @@
+assert.notEqual(1,1);
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.assertNotPass.js b/e2e/tests/assert/tests/assert.assertNotPass.js
new file mode 100644
index 00000000..cdb9b3b1
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.assertNotPass.js
@@ -0,0 +1 @@
+assert.notEqual(1,2);
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.assertPass.js b/e2e/tests/assert/tests/assert.assertPass.js
new file mode 100644
index 00000000..3c7f72f3
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.assertPass.js
@@ -0,0 +1 @@
+assert.equal(1,1);
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.failFail.js b/e2e/tests/assert/tests/assert.failFail.js
new file mode 100644
index 00000000..bfec9edc
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.failFail.js
@@ -0,0 +1 @@
+assert.fail('fail');
\ No newline at end of file
diff --git a/e2e/tests/assert/tests/assert.failPass.js b/e2e/tests/assert/tests/assert.failPass.js
new file mode 100644
index 00000000..fab568ab
--- /dev/null
+++ b/e2e/tests/assert/tests/assert.failPass.js
@@ -0,0 +1 @@
+assert.fail();
\ No newline at end of file
diff --git a/e2e/tests/date.js b/e2e/tests/date.js
new file mode 100644
index 00000000..6dbdc420
--- /dev/null
+++ b/e2e/tests/date.js
@@ -0,0 +1,29 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/date/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('date', () => {
+ it('now correct', async () => {
+ const response = await cliProcess.execute('1.js');
+ shouldPass(response);
+ });
+
+ it('now correct 2', async () => {
+ const response = await cliProcess.execute('2.js');
+ shouldPass(response);
+ });
+
+ it('fromNow correct', async () => {
+ const response = await cliProcess.execute('3.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/date/tests/1.js b/e2e/tests/date/tests/1.js
new file mode 100644
index 00000000..43bf2969
--- /dev/null
+++ b/e2e/tests/date/tests/1.js
@@ -0,0 +1,2 @@
+const d = date.now('HH:MM');
+log.info(d);
\ No newline at end of file
diff --git a/e2e/tests/date/tests/2.js b/e2e/tests/date/tests/2.js
new file mode 100644
index 00000000..4ca2329b
--- /dev/null
+++ b/e2e/tests/date/tests/2.js
@@ -0,0 +1,2 @@
+const d = date.now();
+log.info(d);
\ No newline at end of file
diff --git a/e2e/tests/date/tests/3.js b/e2e/tests/date/tests/3.js
new file mode 100644
index 00000000..78911da0
--- /dev/null
+++ b/e2e/tests/date/tests/3.js
@@ -0,0 +1,2 @@
+const d = date.fromNow();
+log.info(d);
\ No newline at end of file
diff --git a/e2e/tests/db.js b/e2e/tests/db.js
new file mode 100644
index 00000000..aab62485
--- /dev/null
+++ b/e2e/tests/db.js
@@ -0,0 +1,39 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/db/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('db-module', () => {
+ it('[setConnectionString] correct', async () => {
+ const response = await cliProcess.execute('db.setConnectionStringPass.js');
+ shouldPass(response);
+ });
+
+ it('[setConnectionString] not correct', async () => {
+ const response = await cliProcess.execute('db.setConnectionStringFail.js');
+ shouldFail(response);
+ });
+
+ it('[executeQuery] correct', async () => {
+ const response = await cliProcess.execute('db.executeQueryPass.js');
+ shouldPass(response);
+ });
+
+ it('[getScalar] correct', async () => {
+ const response = await cliProcess.execute('db.getScalarPass.js');
+ shouldPass(response);
+ });
+
+ it('[executeNonQuery] correct', async () => {
+ const response = await cliProcess.execute('db.executeNonQueryPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/db/assets/NOT_VALID_NAME.db b/e2e/tests/db/assets/NOT_VALID_NAME.db
new file mode 100644
index 00000000..e69de29b
diff --git a/e2e/tests/db/assets/caps.js b/e2e/tests/db/assets/caps.js
new file mode 100644
index 00000000..f960d534
--- /dev/null
+++ b/e2e/tests/db/assets/caps.js
@@ -0,0 +1,4 @@
+const path = require('path');
+const dbPath = path.resolve(__dirname, '../assets/test.db');
+
+module.exports = `DRIVER=SQLite3 ODBC Driver;Database=${dbPath};LongNames=0;Timeout=2000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;`;
\ No newline at end of file
diff --git a/e2e/tests/db/assets/test.db b/e2e/tests/db/assets/test.db
new file mode 100644
index 00000000..ef1d850f
Binary files /dev/null and b/e2e/tests/db/assets/test.db differ
diff --git a/e2e/tests/db/tests/db.executeNonQueryPass.js b/e2e/tests/db/tests/db.executeNonQueryPass.js
new file mode 100644
index 00000000..7ee902d6
--- /dev/null
+++ b/e2e/tests/db/tests/db.executeNonQueryPass.js
@@ -0,0 +1,19 @@
+const conStr = require('../assets/caps');
+db.setConnectionString(conStr);
+
+// add new data to the table
+db.executeNonQuery('insert into a_table (a, b ,c) values ("aaaa", "bbbb", 1)');
+
+// verify that it was added
+let scalar = db.getScalar('select b from a_table where a = "aaaa"');
+log.info(scalar)
+assert.equal(scalar === 'bbbb', true);
+
+// cleanup
+db.executeNonQuery('delete from a_table where a = "aaaa"');
+
+// verify cleanup
+const allRows = db.executeQuery('select * from a_table');
+log.info(allRows);
+log.info(allRows.length);
+assert.equal(allRows && Array.isArray(allRows) && allRows.length === 2, true);
\ No newline at end of file
diff --git a/e2e/tests/db/tests/db.executeQueryPass.js b/e2e/tests/db/tests/db.executeQueryPass.js
new file mode 100644
index 00000000..f27aae93
--- /dev/null
+++ b/e2e/tests/db/tests/db.executeQueryPass.js
@@ -0,0 +1,6 @@
+const conStr = require('../assets/caps');
+db.setConnectionString(conStr);
+
+var allRows = db.executeQuery('select * from a_table');
+log.info(allRows.length);
+assert.equal(allRows && Array.isArray(allRows) && allRows.length === 2, true);
\ No newline at end of file
diff --git a/e2e/tests/db/tests/db.getScalarPass.js b/e2e/tests/db/tests/db.getScalarPass.js
new file mode 100644
index 00000000..36086bf3
--- /dev/null
+++ b/e2e/tests/db/tests/db.getScalarPass.js
@@ -0,0 +1,7 @@
+const conStr = require('../assets/caps');
+db.setConnectionString(conStr);
+
+var scalar = db.getScalar('select c from a_table where a = "foo"');
+log.info(scalar)
+
+assert.equal(scalar === 1, true);
\ No newline at end of file
diff --git a/e2e/tests/db/tests/db.setConnectionStringFail.js b/e2e/tests/db/tests/db.setConnectionStringFail.js
new file mode 100644
index 00000000..5204aa33
--- /dev/null
+++ b/e2e/tests/db/tests/db.setConnectionStringFail.js
@@ -0,0 +1,10 @@
+const path = require('path');
+const dbPath = path.resolve(__dirname, '../assets/NOT_VALID_NAME.db');
+
+const conStr = `DRIVER=SQLite3 ODBC Driver;Database=${dbPath};LongNames=0;Timeout=2000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;`;
+db.setConnectionString(conStr);
+
+var allRows = db.executeQuery('select * from a_table');
+log.info(allRows);
+log.info(allRows.length);
+assert.equal(allRows && Array.isArray(allRows) && allRows.length === 2, true);
\ No newline at end of file
diff --git a/e2e/tests/db/tests/db.setConnectionStringPass.js b/e2e/tests/db/tests/db.setConnectionStringPass.js
new file mode 100644
index 00000000..f27aae93
--- /dev/null
+++ b/e2e/tests/db/tests/db.setConnectionStringPass.js
@@ -0,0 +1,6 @@
+const conStr = require('../assets/caps');
+db.setConnectionString(conStr);
+
+var allRows = db.executeQuery('select * from a_table');
+log.info(allRows.length);
+assert.equal(allRows && Array.isArray(allRows) && allRows.length === 2, true);
\ No newline at end of file
diff --git a/e2e/tests/email.js b/e2e/tests/email.js
new file mode 100644
index 00000000..e572983d
--- /dev/null
+++ b/e2e/tests/email.js
@@ -0,0 +1,24 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/email/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('email', () => {
+ it('init correct', async () => {
+ const response = await cliProcess.execute('1.js');
+ shouldPass(response);
+ });
+
+ it('getLastEmail not correct', async () => {
+ const response = await cliProcess.execute('2.js');
+ shouldFail(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/email/tests/1.js b/e2e/tests/email/tests/1.js
new file mode 100644
index 00000000..a8fd020e
--- /dev/null
+++ b/e2e/tests/email/tests/1.js
@@ -0,0 +1 @@
+email.init();
\ No newline at end of file
diff --git a/e2e/tests/email/tests/2.js b/e2e/tests/email/tests/2.js
new file mode 100644
index 00000000..e602db56
--- /dev/null
+++ b/e2e/tests/email/tests/2.js
@@ -0,0 +1,2 @@
+email.init();
+email.getLastEmail();
\ No newline at end of file
diff --git a/e2e/tests/http.js b/e2e/tests/http.js
new file mode 100644
index 00000000..b9026b91
--- /dev/null
+++ b/e2e/tests/http.js
@@ -0,0 +1,36 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/http/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('http', () => {
+ it('get correct', async () => {
+ const response = await cliProcess.execute('1.js');
+ shouldPass(response);
+ });
+
+ it('post correct', async () => {
+ const response = await cliProcess.execute('2.js');
+ shouldPass(response);
+ });
+ it('put not correct', async () => {
+ const response = await cliProcess.execute('3.js');
+ shouldFail(response);
+ });
+ it('delete correct', async () => {
+ const response = await cliProcess.execute('4.js');
+ shouldFail(response);
+ });
+ it('getResponseHeaders correct', async () => {
+ const response = await cliProcess.execute('5.js');
+ shouldPass(response);
+ });
+});
diff --git a/e2e/tests/http/tests/1.js b/e2e/tests/http/tests/1.js
new file mode 100644
index 00000000..6f629ef2
--- /dev/null
+++ b/e2e/tests/http/tests/1.js
@@ -0,0 +1 @@
+http.get('https://www.wikipedia.org/');
\ No newline at end of file
diff --git a/e2e/tests/http/tests/2.js b/e2e/tests/http/tests/2.js
new file mode 100644
index 00000000..a479fedd
--- /dev/null
+++ b/e2e/tests/http/tests/2.js
@@ -0,0 +1 @@
+http.post('https://www.wikipedia.org/');
\ No newline at end of file
diff --git a/e2e/tests/http/tests/3.js b/e2e/tests/http/tests/3.js
new file mode 100644
index 00000000..3ce7eb99
--- /dev/null
+++ b/e2e/tests/http/tests/3.js
@@ -0,0 +1 @@
+http.put('https://www.wikipedia.org/');
\ No newline at end of file
diff --git a/e2e/tests/http/tests/4.js b/e2e/tests/http/tests/4.js
new file mode 100644
index 00000000..3ce7eb99
--- /dev/null
+++ b/e2e/tests/http/tests/4.js
@@ -0,0 +1 @@
+http.put('https://www.wikipedia.org/');
\ No newline at end of file
diff --git a/e2e/tests/http/tests/5.js b/e2e/tests/http/tests/5.js
new file mode 100644
index 00000000..ccef1a71
--- /dev/null
+++ b/e2e/tests/http/tests/5.js
@@ -0,0 +1,2 @@
+const headers = http.getResponseHeaders('https://www.wikipedia.org/');
+log.info(headers);
\ No newline at end of file
diff --git a/e2e/tests/log.js b/e2e/tests/log.js
new file mode 100644
index 00000000..61d770e3
--- /dev/null
+++ b/e2e/tests/log.js
@@ -0,0 +1,31 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/log/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('log', () => {
+ it('info correct', async () => {
+ const response = await cliProcess.execute('1.js');
+ shouldPass(response);
+ });
+ it('error correct', async () => {
+ const response = await cliProcess.execute('2.js');
+ shouldPass(response);
+ });
+ it('debug correct', async () => {
+ const response = await cliProcess.execute('3.js');
+ shouldPass(response);
+ });
+ it('warn correct', async () => {
+ const response = await cliProcess.execute('4.js');
+ shouldPass(response);
+ });
+});
diff --git a/e2e/tests/log/tests/1.js b/e2e/tests/log/tests/1.js
new file mode 100644
index 00000000..855846ec
--- /dev/null
+++ b/e2e/tests/log/tests/1.js
@@ -0,0 +1 @@
+log.info('info');
\ No newline at end of file
diff --git a/e2e/tests/log/tests/2.js b/e2e/tests/log/tests/2.js
new file mode 100644
index 00000000..8f6313c7
--- /dev/null
+++ b/e2e/tests/log/tests/2.js
@@ -0,0 +1 @@
+log.error('error');
\ No newline at end of file
diff --git a/e2e/tests/log/tests/3.js b/e2e/tests/log/tests/3.js
new file mode 100644
index 00000000..94d1fb0d
--- /dev/null
+++ b/e2e/tests/log/tests/3.js
@@ -0,0 +1 @@
+log.debug('debug');
\ No newline at end of file
diff --git a/e2e/tests/log/tests/4.js b/e2e/tests/log/tests/4.js
new file mode 100644
index 00000000..1014107e
--- /dev/null
+++ b/e2e/tests/log/tests/4.js
@@ -0,0 +1 @@
+log.warn('warn')
\ No newline at end of file
diff --git a/e2e/tests/mob.android.js b/e2e/tests/mob.android.js
new file mode 100644
index 00000000..3e6f6d2e
--- /dev/null
+++ b/e2e/tests/mob.android.js
@@ -0,0 +1,229 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/mob.android/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('mob-android-module', () => {
+ it('[getCapabilities] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getCapabilitiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[init] correct', async () => {
+ const response = await cliProcess.execute('mob.android.initPass.js');
+ shouldPass(response);
+ });
+
+ it('[dispose] correct', async () => {
+ const response = await cliProcess.execute('mob.android.disposePass.js');
+ shouldPass(response);
+ });
+
+ it('[transaction] correct', async () => {
+ const response = await cliProcess.execute('mob.android.transactionPass.js');
+ shouldPass(response);
+ });
+
+ it('[installApp] correct', async () => {
+ const response = await cliProcess.execute('mob.android.installAppPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertAccept] correct', async () => {
+ const response = await cliProcess.execute('mob.android.alertAcceptPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertDismiss] correct', async () => {
+ const response = await cliProcess.execute('mob.android.alertDismissPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertText] correct', async () => {
+ const response = await cliProcess.execute('mob.android.assertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[click] correct', async () => {
+ const response = await cliProcess.execute('mob.android.clickPass.js');
+ shouldPass(response);
+ });
+
+ it('[takeScreenshot] correct', async () => {
+ const response = await cliProcess.execute('mob.android.takeScreenshotPass.js');
+ shouldPass(response);
+ });
+
+ it('[closeApp] correct', async () => {
+ const response = await cliProcess.execute('mob.android.closeAppPass.js');
+ shouldPass(response);
+ });
+
+ it('[getSource] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[isAppInstalled] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isAppInstalledPass.js');
+ shouldPass(response);
+ });
+
+ it('[resetApp] correct', async () => {
+ const response = await cliProcess.execute('mob.android.resetAppPass.js');
+ shouldPass(response);
+ });
+
+ it('[removeApp] correct', async () => {
+ const response = await cliProcess.execute('mob.android.removeAppPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCurrentActivity] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getCurrentActivityPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCurrentPackage] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getCurrentPackagePass.js');
+ shouldPass(response);
+ });
+
+ it('[getDeviceLogs] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getDeviceLogsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getBrowserLogs] fail', async () => {
+ const response = await cliProcess.execute('mob.android.getBrowserLogsFail.js');
+ shouldPass(response);
+ });
+
+ it('[getDeviceTime] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getDeviceTimePass.js');
+ shouldPass(response);
+ });
+
+ it('[isClickable] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isClickablePass.js');
+ shouldPass(response);
+ });
+
+ it('[isExist] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[isVisible] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[isWebViewContext] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isWebViewContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[launchApp] correct', async () => {
+ const response = await cliProcess.execute('mob.android.launchAppPass.js');
+ shouldPass(response);
+ });
+
+ it('[sendKeys] [findElement] [type] [waitForVisible] [waitForExist] [clear] [hideKeyboard] correct', async () => {
+ const response = await cliProcess.execute('mob.android.sendKeysPass.js');
+ shouldPass(response);
+ });
+
+ it('[setContext] correct', async () => {
+ const response = await cliProcess.execute('mob.android.setContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[setNativeContext] correct', async () => {
+ const response = await cliProcess.execute('mob.android.setNativeContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[swipeScreen] correct', async () => {
+ const response = await cliProcess.execute('mob.android.swipeScreenPass.js');
+ shouldPass(response);
+ });
+
+ it('[getText] [getLocation] [tap] [clickLong] [clickMultipleTimes] [pause] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[findElements] correct', async () => {
+ const response = await cliProcess.execute('mob.android.findElementsPass.js');
+ shouldPass(response);
+ });
+
+ it('[back] correct', async () => {
+ const response = await cliProcess.execute('mob.android.backPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAlertText] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getAlertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAppiumLogs] correct', async () => {
+ const response = await cliProcess.execute('mob.android.getAppiumLogsPass.js');
+ shouldPass(response);
+ });
+
+ it('[setTimeout] correct', async () => {
+ const response = await cliProcess.execute('mob.android.setTimeoutPass.js');
+ shouldPass(response);
+ });
+
+ it('[swipeElement] correct', async () => {
+ const response = await cliProcess.execute('mob.android.swipeElementPass.js');
+ shouldPass(response);
+ });
+
+ it('[swipe] correct', async () => {
+ const response = await cliProcess.execute('mob.android.swipePass.js');
+ shouldPass(response);
+ });
+
+ it('[scrollIntoElement] correct', async () => {
+ const response = await cliProcess.execute('mob.android.scrollIntoElementPass.js');
+ shouldPass(response);
+ });
+
+ it('[isSelected] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isSelectedPass.js');
+ shouldPass(response);
+ });
+
+ it('[isChecked] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isCheckedPass.js');
+ shouldPass(response);
+ });
+
+ it('[isCheckable] correct', async () => {
+ const response = await cliProcess.execute('mob.android.isCheckablePass.js');
+ shouldPass(response);
+ });
+
+ it('[enableNetwork] correct', async () => {
+ const response = await cliProcess.execute('mob.android.enableNetworkPass.js');
+ shouldPass(response);
+ });
+
+ it('[dragAndDrop] correct', async () => {
+ const response = await cliProcess.execute('mob.android.dragAndDropPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/mob.android/assets/ApiDemos-debug.apk b/e2e/tests/mob.android/assets/ApiDemos-debug.apk
new file mode 100644
index 00000000..62a1fd60
Binary files /dev/null and b/e2e/tests/mob.android/assets/ApiDemos-debug.apk differ
diff --git a/e2e/tests/mob.android/assets/Volume-pre-production.apk b/e2e/tests/mob.android/assets/Volume-pre-production.apk
new file mode 100644
index 00000000..e49dfa45
Binary files /dev/null and b/e2e/tests/mob.android/assets/Volume-pre-production.apk differ
diff --git a/e2e/tests/mob.android/assets/caps.js b/e2e/tests/mob.android/assets/caps.js
new file mode 100644
index 00000000..100f8c23
--- /dev/null
+++ b/e2e/tests/mob.android/assets/caps.js
@@ -0,0 +1,4 @@
+module.exports = {
+ platformName: 'Android',
+ autoGrantPermissions: true
+};
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.alertAcceptPass.js b/e2e/tests/mob.android/tests/mob.android.alertAcceptPass.js
new file mode 100644
index 00000000..8c6af05d
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.alertAcceptPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.TextView[@content-desc="Alert Dialogs"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.Button[@content-desc="OK Cancel dialog with a message"]');
+
+mob.alertAccept();
+
+mob.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.alertDismissPass.js b/e2e/tests/mob.android/tests/mob.android.alertDismissPass.js
new file mode 100644
index 00000000..95e45e59
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.alertDismissPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.TextView[@content-desc="Alert Dialogs"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.Button[@content-desc="OK Cancel dialog with a message"]');
+
+mob.alertDismiss();
+
+mob.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.assertTextPass.js b/e2e/tests/mob.android/tests/mob.android.assertTextPass.js
new file mode 100644
index 00000000..25149a44
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.assertTextPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Text"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.TextView[@content-desc="LogTextBox"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.Button[@content-desc="Add"]');
+
+mob.pause(5000);
+
+mob.assertText('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.TextView', 'This is a test');
diff --git a/e2e/tests/mob.android/tests/mob.android.assertValuePass.js b/e2e/tests/mob.android/tests/mob.android.assertValuePass.js
new file mode 100644
index 00000000..621c1427
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.assertValuePass.js
@@ -0,0 +1,68 @@
+// const caps = require('../assets/caps');
+// const path = require('path');
+// const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+// caps.app = apkPath;
+// mob.init(caps);
+
+// mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+// mob.pause(5000);
+
+// mob.click('//android.widget.TextView[@content-desc="Spinner"]');
+
+// mob.pause(5000);
+
+// const value = mob.getValue('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.Spinner[1]');
+
+// log.info(value);
+
+
+
+
+
+
+// mob.click('//android.widget.TextView[@content-desc="Controls"]');
+
+// mob.pause(5000);
+
+// mob.click('//android.widget.TextView[@content-desc="2. Dark Theme"]');
+
+// mob.pause(5000);
+
+// mob.hideKeyboard("pressKey", "Done");
+
+// mob.pause(5000);
+
+// mob.type('/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout[2]/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.EditText', "0544501591");
+
+// mob.pause(5000);
+
+// const value = mob.getValue('id=io.appium.android.apis:id/edit');
+
+// log.info(value);
+
+
+
+
+
+
+
+
+
+// const caps = require('../assets/caps');
+// const path = require('path');
+// const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+// caps.app = apkPath;
+// mob.init(caps);
+
+// mob.transaction('Open celcom app');
+// mob.waitForVisible("id=com.cellcom.volume:id/auth_phone_number");
+// var el1 = mob.findElement("id=com.cellcom.volume:id/auth_phone_number");
+// mob.click(el1);
+// mob.transaction('type phone');
+// mob.type(el1, "0544501591");
+// mob.sendKeys("Enter");
+// mob.pause(3000);
+
+// const value = mob.getValue(el1);
+// log.info(value);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.backPass.js b/e2e/tests/mob.android/tests/mob.android.backPass.js
new file mode 100644
index 00000000..dd2a0c12
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.backPass.js
@@ -0,0 +1,16 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+mob.pause(5000);
+
+mob.back();
+
+mob.pause(5000);
+
+mob.isVisible('//android.widget.TextView[@content-desc="Views"]');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.clickPass.js b/e2e/tests/mob.android/tests/mob.android.clickPass.js
new file mode 100644
index 00000000..4e228bb2
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.clickPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Text"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.TextView[@content-desc="LogTextBox"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.Button[@content-desc="Add"]');
+
+mob.pause(5000);
+
+mob.assertText('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.TextView', 'This is a test');
diff --git a/e2e/tests/mob.android/tests/mob.android.closeAppPass.js b/e2e/tests/mob.android/tests/mob.android.closeAppPass.js
new file mode 100644
index 00000000..4014f2be
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.closeAppPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+
+mob.init(caps);
+mob.setTimeout(6000);
+mob.closeApp();
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.disposePass.js b/e2e/tests/mob.android/tests/mob.android.disposePass.js
new file mode 100644
index 00000000..f9096d56
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.disposePass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.dispose();
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.dragAndDropPass.js b/e2e/tests/mob.android/tests/mob.android.dragAndDropPass.js
new file mode 100644
index 00000000..2e4e281d
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.dragAndDropPass.js
@@ -0,0 +1,26 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+mob.click('//android.widget.TextView[@content-desc="Drag and Drop"]');
+
+mob.pause(5000);
+
+const dropElm = mob.findElement('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.RelativeLayout/android.view.View[2]');
+
+const dropLocation = dropElm.getLocation();
+
+log.info(dropLocation);
+
+mob.dragAndDrop(
+ "/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.RelativeLayout/android.view.View[1]",
+ dropLocation.x+50,
+ dropLocation.y+50
+);
+
+mob.pause(15000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.enableNetworkPass.js b/e2e/tests/mob.android/tests/mob.android.enableNetworkPass.js
new file mode 100644
index 00000000..782663c8
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.enableNetworkPass.js
@@ -0,0 +1,18 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.pause(5000);
+
+mob.enableNetwork(false,false);
+
+mob.pause(15000);
+
+mob.enableNetwork(true,true);
+
+mob.pause(5000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.findElementsPass.js b/e2e/tests/mob.android/tests/mob.android.findElementsPass.js
new file mode 100644
index 00000000..db4d2442
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.findElementsPass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const elements = mob.findElements('//android.widget.TextView');
+
+log.info(elements)
+log.info(elements.length);
+
+const elementsValid = elements.length > 1;
+assert.equal(elementsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getAlertTextPass.js b/e2e/tests/mob.android/tests/mob.android.getAlertTextPass.js
new file mode 100644
index 00000000..39c15b14
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getAlertTextPass.js
@@ -0,0 +1,23 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.TextView[@content-desc="Alert Dialogs"]');
+
+mob.pause(5000);
+
+mob.click('//android.widget.Button[@content-desc="OK Cancel dialog with a message"]');
+
+const alertText = mob.getAlertText();
+
+log.info(alertText);
+
+const alertTextCorrect = alertText && typeof alertText === 'string' && alertText.length > 0 && alertText.includes('Lorem ipsum dolor');
+assert.equal(alertTextCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getAppiumLogsPass.js b/e2e/tests/mob.android/tests/mob.android.getAppiumLogsPass.js
new file mode 100644
index 00000000..4e6d1012
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getAppiumLogsPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+caps.get_server_logs = true;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const logs = mob.getAppiumLogs();
+log.info(logs.length);
+const logsCorrect = logs && Array.isArray(logs);
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getBrowserLogsFail.js b/e2e/tests/mob.android/tests/mob.android.getBrowserLogsFail.js
new file mode 100644
index 00000000..fee771bb
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getBrowserLogsFail.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const logs = mob.getBrowserLogs();
+log.info(logs.length);
+const logsCorrect = logs && Array.isArray(logs) && logs.length > 0;
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getCapabilitiesPass.js b/e2e/tests/mob.android/tests/mob.android.getCapabilitiesPass.js
new file mode 100644
index 00000000..3cc4e841
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getCapabilitiesPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+
+mob.init(caps);
+mob.setTimeout(6000);
+
+const apkPath2 = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+
+log.info(apkPath2);
+
+mob.installApp(apkPath2);
+const capabilities = mob.getCapabilities();
+
+log.info(capabilities);
+
+const capsValid = !!capabilities && !!capabilities.platformName;
+assert.equal(capsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getCurrentActivityPass.js b/e2e/tests/mob.android/tests/mob.android.getCurrentActivityPass.js
new file mode 100644
index 00000000..a8a97ba6
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getCurrentActivityPass.js
@@ -0,0 +1,13 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+let activity = mob.getCurrentActivity();
+log.info(activity);
+const activityCorrect = activity && typeof activity === 'string' && activity.length > 0;
+
+assert.equal(activityCorrect, true);
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getCurrentPackagePass.js b/e2e/tests/mob.android/tests/mob.android.getCurrentPackagePass.js
new file mode 100644
index 00000000..c732ab8d
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getCurrentPackagePass.js
@@ -0,0 +1,13 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+let pkg = mob.getCurrentPackage();
+log.info(pkg);
+const packageCorrect = pkg && typeof pkg === 'string' && pkg.length > 0;
+
+assert.equal(packageCorrect, true);
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getDeviceLogsPass.js b/e2e/tests/mob.android/tests/mob.android.getDeviceLogsPass.js
new file mode 100644
index 00000000..b8688a98
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getDeviceLogsPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const logs = mob.getDeviceLogs();
+log.info(logs.length);
+const logsCorrect = logs && Array.isArray(logs) && logs.length > 0;
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getDeviceTimePass.js b/e2e/tests/mob.android/tests/mob.android.getDeviceTimePass.js
new file mode 100644
index 00000000..806ebec0
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getDeviceTimePass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const time = mob.getDeviceTime();
+log.info(time);
+
+const timeCorrect = time && typeof time === 'string' && time.length > 0;
+assert.equal(timeCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getSourcePass.js b/e2e/tests/mob.android/tests/mob.android.getSourcePass.js
new file mode 100644
index 00000000..cb1b5106
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getSourcePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+
+mob.init(caps);
+mob.setTimeout(6000);
+const source = mob.getSource();
+const sourceCorrect = source && typeof source === 'string' && source.length > 0;
+assert.equal(sourceCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.getTextPass.js b/e2e/tests/mob.android/tests/mob.android.getTextPass.js
new file mode 100644
index 00000000..368f4fc6
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.getTextPass.js
@@ -0,0 +1,34 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const textLocator = '//android.widget.TextView[@content-desc="Text"]';
+
+var el1 = mob.findElement(textLocator);
+
+const location = mob.getLocation(el1);
+log.info(location);
+
+const locationCorrect = !!location && typeof location.x !== 'undefined' && typeof location.y !== 'undefined';
+assert.equal(locationCorrect, true);
+
+mob.tap(location.x,location.y);
+
+mob.pause(3000);
+
+mob.clickLong(textLocator, 1000);
+
+mob.pause(3000);
+
+mob.clickMultipleTimes('//android.widget.TextView[@content-desc="Linkify"]', 2);
+
+var el1 = mob.findElement("/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.ScrollView/android.widget.LinearLayout/android.widget.TextView[4]");
+
+const text = mob.getText(el1);
+log.info(text);
+const textCorrect = text && typeof text === 'string' && text.length > 0;
+assert.equal(textCorrect, true);
+
diff --git a/e2e/tests/mob.android/tests/mob.android.initPass.js b/e2e/tests/mob.android/tests/mob.android.initPass.js
new file mode 100644
index 00000000..ea8d7cfb
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.initPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+
+mob.init(caps);
+mob.setTimeout(6000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.installAppPass.js b/e2e/tests/mob.android/tests/mob.android.installAppPass.js
new file mode 100644
index 00000000..cea93455
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.installAppPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+
+mob.init(caps);
+mob.setTimeout(6000);
+const apkPath2 = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+log.info(apkPath2);
+mob.installApp(apkPath2);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isAppInstalledPass.js b/e2e/tests/mob.android/tests/mob.android.isAppInstalledPass.js
new file mode 100644
index 00000000..22b21428
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isAppInstalledPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+const installed = mob.isAppInstalled('com.cellcom.volume');
+log.info(installed);
+assert.equal(installed, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isCheckablePass.js b/e2e/tests/mob.android/tests/mob.android.isCheckablePass.js
new file mode 100644
index 00000000..83ee214f
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isCheckablePass.js
@@ -0,0 +1,18 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+mob.click('//android.widget.TextView[@content-desc="Controls"]');
+
+mob.click('//android.widget.TextView[@content-desc="2. Dark Theme"]');
+mob.hideKeyboard("pressKey", "Done");
+
+
+let checkable = mob.isCheckable('//android.widget.CheckBox[@content-desc="Checkbox 1"]');
+log.info(checkable);
+assert.equal(checkable, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isCheckedPass.js b/e2e/tests/mob.android/tests/mob.android.isCheckedPass.js
new file mode 100644
index 00000000..9d7f0443
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isCheckedPass.js
@@ -0,0 +1,26 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+mob.click('//android.widget.TextView[@content-desc="Controls"]');
+
+mob.click('//android.widget.TextView[@content-desc="2. Dark Theme"]');
+mob.hideKeyboard("pressKey", "Done");
+
+let checked = mob.isChecked('//android.widget.CheckBox[@content-desc="Checkbox 1"]');
+log.info(checked);
+assert.equal(checked, false);
+
+const loc1 = mob.getLocation('//android.widget.CheckBox[@content-desc="Checkbox 1"]');
+mob.tap(loc1.x,loc1.y);
+
+mob.pause(15000);
+
+checked = mob.isChecked('//android.widget.CheckBox[@content-desc="Checkbox 1"]');
+log.info(checked);
+assert.equal(checked, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isClickablePass.js b/e2e/tests/mob.android/tests/mob.android.isClickablePass.js
new file mode 100644
index 00000000..8975370a
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isClickablePass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="Text"]');
+
+mob.click('//android.widget.TextView[@content-desc="Marquee"]');
+
+const clickable = mob.isClickable('//android.widget.Button[@content-desc="This use the default marquee animation limit of 3"]');
+log.info(clickable);
+assert.equal(clickable, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isExistPass.js b/e2e/tests/mob.android/tests/mob.android.isExistPass.js
new file mode 100644
index 00000000..c856e00b
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isExistPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const exist = mob.isExist('//android.widget.TextView[@content-desc="Text"]');
+log.info(exist);
+assert.equal(exist, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isSelectedPass.js b/e2e/tests/mob.android/tests/mob.android.isSelectedPass.js
new file mode 100644
index 00000000..44384714
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isSelectedPass.js
@@ -0,0 +1,26 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.click('//android.widget.TextView[@content-desc="Views"]');
+
+mob.click('//android.widget.TextView[@content-desc="Gallery"]');
+
+mob.click('//android.widget.TextView[@content-desc="1. Photos"]');
+
+mob.hideKeyboard("pressKey", "Done");
+
+let selected = mob.isSelected('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.Gallery/android.widget.ImageView[1]');
+log.info(selected);
+assert.equal(selected, true);
+
+const loc1 = mob.getLocation('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.Gallery/android.widget.ImageView[2]');
+mob.tap(loc1.x,loc1.y);
+
+mob.pause(5000);
+
+selected = mob.isSelected('/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.Gallery/android.widget.ImageView[1]');
+log.info(selected);
+assert.equal(selected, false);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isVisiblePass.js b/e2e/tests/mob.android/tests/mob.android.isVisiblePass.js
new file mode 100644
index 00000000..64e209b0
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isVisiblePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+const visible = mob.isVisible('//android.widget.TextView[@content-desc="Text"]');
+log.info(visible);
+assert.equal(visible, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.isWebViewContextPass.js b/e2e/tests/mob.android/tests/mob.android.isWebViewContextPass.js
new file mode 100644
index 00000000..f2746396
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.isWebViewContextPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.waitForVisible('//android.widget.TextView[@content-desc="Text"]');
+const isWebViewContext = mob.isWebViewContext();
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, false);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.launchAppPass.js b/e2e/tests/mob.android/tests/mob.android.launchAppPass.js
new file mode 100644
index 00000000..ea3f7b97
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.launchAppPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.closeApp();
+mob.pause(2000);
+mob.launchApp();
+mob.pause(2000);
+mob.waitForVisible('//android.widget.TextView[@content-desc="Text"]');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.removeAppPass.js b/e2e/tests/mob.android/tests/mob.android.removeAppPass.js
new file mode 100644
index 00000000..ec539301
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.removeAppPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.removeApp('com.cellcom.volume');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.resetAppPass.js b/e2e/tests/mob.android/tests/mob.android.resetAppPass.js
new file mode 100644
index 00000000..c36b37ff
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.resetAppPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.resetApp();
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.scrollIntoElementPass.js b/e2e/tests/mob.android/tests/mob.android.scrollIntoElementPass.js
new file mode 100644
index 00000000..d65d09d0
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.scrollIntoElementPass.js
@@ -0,0 +1,28 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+let isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+let isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, false);
+
+
+mob.scrollIntoElement(
+ '/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.ListView',
+ '//android.widget.TextView[@content-desc="Voice Recognition"]',
+ 0,
+ 10
+);
+
+mob.pause(5000);
+
+isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.sendKeysPass.js b/e2e/tests/mob.android/tests/mob.android.sendKeysPass.js
new file mode 100644
index 00000000..33cfcd49
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.sendKeysPass.js
@@ -0,0 +1,31 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+mob.click('//android.widget.TextView[@content-desc="Search"]');
+
+mob.click('//android.widget.TextView[@content-desc="Invoke Search"]');
+
+const input = '/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.LinearLayout/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.EditText';
+
+mob.waitForVisible(input);
+mob.waitForExist(input);
+
+var el1 = mob.findElement(input);
+mob.click(el1);
+mob.transaction('type phone');
+mob.type(el1, "0544501591");
+mob.sendKeys("Enter");
+
+mob.pause(6000);
+
+mob.hideKeyboard("pressKey", "Search");
+
+mob.clear(el1);
+
+mob.pause(3000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.setContextPass.js b/e2e/tests/mob.android/tests/mob.android.setContextPass.js
new file mode 100644
index 00000000..db2c08e1
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.setContextPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.setContext('NATIVE_APP');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.setNativeContextPass.js b/e2e/tests/mob.android/tests/mob.android.setNativeContextPass.js
new file mode 100644
index 00000000..63195265
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.setNativeContextPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+mob.setNativeContext();
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.setTimeoutPass.js b/e2e/tests/mob.android/tests/mob.android.setTimeoutPass.js
new file mode 100644
index 00000000..843b7d8e
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.setTimeoutPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.swipeElementPass.js b/e2e/tests/mob.android/tests/mob.android.swipeElementPass.js
new file mode 100644
index 00000000..2baeffc6
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.swipeElementPass.js
@@ -0,0 +1,24 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+let isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+let isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, false);
+
+mob.pause(5000);
+
+mob.swipeElement('//android.widget.TextView[@content-desc="Service"]', 0, 200);
+
+mob.pause(5000);
+
+isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, true);
diff --git a/e2e/tests/mob.android/tests/mob.android.swipePass.js b/e2e/tests/mob.android/tests/mob.android.swipePass.js
new file mode 100644
index 00000000..e2c96829
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.swipePass.js
@@ -0,0 +1,24 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+let isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+let isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, false);
+
+mob.pause(5000);
+
+mob.swipe('//android.widget.TextView[@content-desc="Service"]', 0, 200);
+
+mob.pause(5000);
+
+isExist = mob.isExist('//android.widget.TextView[@content-desc="Voice Recognition"]');
+isVisible = mob.isVisible('//android.widget.TextView[@content-desc="Voice Recognition"]');
+
+assert.equal(isVisible && isExist, true);
diff --git a/e2e/tests/mob.android/tests/mob.android.swipeScreenPass.js b/e2e/tests/mob.android/tests/mob.android.swipeScreenPass.js
new file mode 100644
index 00000000..71e18d63
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.swipeScreenPass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/ApiDemos-debug.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.click('//android.widget.TextView[@content-desc="App"]');
+
+mob.swipeScreen(0, 0, 300, 500);
+
+mob.pause(2000);
+mob.setWebViewContext();
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.takeScreenshotPass.js b/e2e/tests/mob.android/tests/mob.android.takeScreenshotPass.js
new file mode 100644
index 00000000..b449da4f
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.takeScreenshotPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+var ss = mob.takeScreenshot();//Take a screenshot of the current page or screen and return it as base64 encoded string.
+const ssCorrect = ss && typeof ss === 'string' && ss.length > 0;
+assert.equal(ssCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mob.android.transactionPass.js b/e2e/tests/mob.android/tests/mob.android.transactionPass.js
new file mode 100644
index 00000000..70f170c9
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mob.android.transactionPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+caps.app = apkPath;
+mob.init(caps);
+mob.transaction('transaction1');
+mob.setTimeout(6000);
+mob.transaction('transaction2');
\ No newline at end of file
diff --git a/e2e/tests/mob.android/tests/mod.android.transactionPass.js b/e2e/tests/mob.android/tests/mod.android.transactionPass.js
new file mode 100644
index 00000000..c3a8c4d0
--- /dev/null
+++ b/e2e/tests/mob.android/tests/mod.android.transactionPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+
+const apkPath = path.resolve(__dirname, '../assets/Volume-pre-production.apk');
+
+caps.app = apkPath;
+mob.init(caps);
+mob.setTimeout(6000);
+
+mob.transaction('Open celcom app');
\ No newline at end of file
diff --git a/e2e/tests/mob.ios.js b/e2e/tests/mob.ios.js
new file mode 100644
index 00000000..b3eb9991
--- /dev/null
+++ b/e2e/tests/mob.ios.js
@@ -0,0 +1,131 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+const before = mocha.before;
+const assert = require('chai').assert;
+
+const afterStart = config.afterStart;
+const testsFolder = '/mob.ios/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('mob-ios-module', () => {
+ before(() => {
+ assert.equal(!!process.env.udid, true, 'Please set "udid" env');
+ assert.equal(!!process.env.deviceName, true, 'Please set "deviceName" env');
+ assert.equal(!!process.env.platformVersion, true, 'Please set "deviceName" platformVersion');
+ });
+
+ it('[getCapabilities] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getCapabilitiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCapabilities] not correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getCapabilitiesFail.js');
+ shouldFail(response);
+ });
+
+ it('[dispose] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.disposePass.js');
+ shouldPass(response);
+ });
+
+ it('[transaction] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.transactionPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertAccept] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.alertAcceptPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertDismiss] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.alertDismissPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertText] [getText] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.assertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertValue] [getValue] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.assertValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[clear] [findElement] [click] [type] [sendKeys] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.clearPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickLong] [clickMultipleTimes] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.clickLongPass.js');
+ shouldPass(response);
+ });
+ it('[findElements] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.findElementsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAlertText] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getAlertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAppiumLogs] not correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getAppiumLogsFail.js');
+ shouldFail(response);
+ });
+
+ it('[getDeviceLogs] not correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getDeviceLogsFail.js');
+ shouldPass(response);
+ });
+
+ it('[getDeviceTime] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getDeviceTimePass.js');
+ shouldPass(response);
+ });
+
+ it('[getLocation] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getLocationPass.js');
+ shouldPass(response);
+ });
+
+ it('[getSource] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.getSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[takeScreenshot] [setTimeout] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.takeScreenshotPass.js');
+ shouldPass(response);
+ });
+
+ it('[isAppInstalled] [closeApp] [launchApp] [resetApp] [removeApp] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.isAppInstalledPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForExist] [waitForVisible] [tap] [isExist] [isVisible] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.waitForExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[setWebViewContext] [setNativeContext] [setContext] [isWebViewContext] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.isWebViewContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[scrollIntoElement] [swipe] [swipeElement] [swipeScreen] correct', async () => {
+ const response = await cliProcess.execute('mob.ios.scrollIntoElementPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/assets/TestApp b/e2e/tests/mob.ios/assets/TestApp
new file mode 100644
index 00000000..dc958e4d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/Default-568h@2x.png b/e2e/tests/mob.ios/assets/TestApp.app/Default-568h@2x.png
new file mode 100644
index 00000000..c881559d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/Default-568h@2x.png differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/objects.nib b/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/objects.nib
new file mode 100644
index 00000000..f058dd3d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/objects.nib differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/runtime.nib b/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/runtime.nib
new file mode 100644
index 00000000..c2a4c26c
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/GestureTestViewController.nib/runtime.nib differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/Info.plist b/e2e/tests/mob.ios/assets/TestApp.app/Info.plist
new file mode 100644
index 00000000..5b368700
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/PkgInfo b/e2e/tests/mob.ios/assets/TestApp.app/PkgInfo
new file mode 100644
index 00000000..bd04210f
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/TestApp.app/PkgInfo
@@ -0,0 +1 @@
+APPL????
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/TestApp b/e2e/tests/mob.ios/assets/TestApp.app/TestApp
new file mode 100644
index 00000000..dc958e4d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/TestApp differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/_CodeSignature/CodeResources b/e2e/tests/mob.ios/assets/TestApp.app/_CodeSignature/CodeResources
new file mode 100644
index 00000000..31f84ff4
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/TestApp.app/_CodeSignature/CodeResources
@@ -0,0 +1,258 @@
+
+
+
+
+ files
+
+ Default-568h@2x.png
+
+ poDYGy1JWXBgPH3/wCEBNbVTOks=
+
+ GestureTestViewController.nib/objects.nib
+
+ lWMGweucNr4UFdTwgB7v6dZct4w=
+
+ GestureTestViewController.nib/runtime.nib
+
+ drVY5ECUzokvBSeU7Ii2SFrschw=
+
+ Info.plist
+
+ nZQtL9wLXbCUGhoJit5Evrdajbw=
+
+ PkgInfo
+
+ n57qDP4tZfLD1rCS43W0B4LQjzE=
+
+ en.lproj/InfoPlist.strings
+
+ hash
+
+ zmV6UqBSo6r1NOz798vd5O4zTBA=
+
+ optional
+
+
+ en.lproj/Localizable.strings
+
+ hash
+
+ i5FCNEf4Khf5CMab7k9hsO+vWJ0=
+
+ optional
+
+
+ en.lproj/MyViewControllerViewController.nib/objects.nib
+
+ hash
+
+ 4eKh9Itu4WXPM8io2IqrZwzJUwA=
+
+ optional
+
+
+ en.lproj/MyViewControllerViewController.nib/runtime.nib
+
+ hash
+
+ 2BQINdc+fKGXcNftRvah54cUfCE=
+
+ optional
+
+
+
+ files2
+
+ Default-568h@2x.png
+
+ hash
+
+ poDYGy1JWXBgPH3/wCEBNbVTOks=
+
+ hash2
+
+ UdHegDh1HZlDpSEYtzMl4sjA9q8uvK4K9OL0sRTFD6M=
+
+
+ GestureTestViewController.nib/objects.nib
+
+ hash
+
+ lWMGweucNr4UFdTwgB7v6dZct4w=
+
+ hash2
+
+ pZB1SkhNtHXMYSBA4itjOHGT1QSFwc1/IQ6Lgzqb67M=
+
+
+ GestureTestViewController.nib/runtime.nib
+
+ hash
+
+ drVY5ECUzokvBSeU7Ii2SFrschw=
+
+ hash2
+
+ pGvXgJ1rx66gH1woqLxwuh4FeavGrxHi8AgIDjUM7u0=
+
+
+ en.lproj/InfoPlist.strings
+
+ hash
+
+ zmV6UqBSo6r1NOz798vd5O4zTBA=
+
+ hash2
+
+ kmHsztpgjvF0JW5f3HdMHm49z1M0CcG8OT1JDQHHE/E=
+
+ optional
+
+
+ en.lproj/Localizable.strings
+
+ hash
+
+ i5FCNEf4Khf5CMab7k9hsO+vWJ0=
+
+ hash2
+
+ HYHNQjwuoAdlCVlsYW/EqQzCMr+mMh77J61qBKGSuhk=
+
+ optional
+
+
+ en.lproj/MyViewControllerViewController.nib/objects.nib
+
+ hash
+
+ 4eKh9Itu4WXPM8io2IqrZwzJUwA=
+
+ hash2
+
+ C9GGlC67rBeMTpxQIs8edc3ghS4lRlm5N3FOj6uMn8U=
+
+ optional
+
+
+ en.lproj/MyViewControllerViewController.nib/runtime.nib
+
+ hash
+
+ 2BQINdc+fKGXcNftRvah54cUfCE=
+
+ hash2
+
+ QpEjsv/FtB761nlMPbqBf7vumh+jLD32Lkh81Oia8ms=
+
+ optional
+
+
+
+ rules
+
+ ^
+
+ ^.*\.lproj/
+
+ optional
+
+ weight
+ 1000
+
+ ^.*\.lproj/locversion.plist$
+
+ omit
+
+ weight
+ 1100
+
+ ^Base\.lproj/
+
+ weight
+ 1010
+
+ ^version.plist$
+
+
+ rules2
+
+ .*\.dSYM($|/)
+
+ weight
+ 11
+
+ ^
+
+ weight
+ 20
+
+ ^(.*/)?\.DS_Store$
+
+ omit
+
+ weight
+ 2000
+
+ ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
+
+ nested
+
+ weight
+ 10
+
+ ^.*
+
+ ^.*\.lproj/
+
+ optional
+
+ weight
+ 1000
+
+ ^.*\.lproj/locversion.plist$
+
+ omit
+
+ weight
+ 1100
+
+ ^Base\.lproj/
+
+ weight
+ 1010
+
+ ^Info\.plist$
+
+ omit
+
+ weight
+ 20
+
+ ^PkgInfo$
+
+ omit
+
+ weight
+ 20
+
+ ^[^/]+$
+
+ nested
+
+ weight
+ 10
+
+ ^embedded\.provisionprofile$
+
+ weight
+ 20
+
+ ^version\.plist$
+
+ weight
+ 20
+
+
+
+
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/InfoPlist.strings b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/InfoPlist.strings
new file mode 100644
index 00000000..3967e063
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/InfoPlist.strings differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/Localizable.strings b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/Localizable.strings
new file mode 100644
index 00000000..ed5825b6
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/Localizable.strings differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/objects.nib b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/objects.nib
new file mode 100644
index 00000000..a1aa6e4d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/objects.nib differ
diff --git a/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/runtime.nib b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/runtime.nib
new file mode 100644
index 00000000..4da0a399
Binary files /dev/null and b/e2e/tests/mob.ios/assets/TestApp.app/en.lproj/MyViewControllerViewController.nib/runtime.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Assets.car b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Assets.car
new file mode 100644
index 00000000..e7717ddb
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Assets.car differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..b3d00e44
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/UITableViewController-YvC-vN-mSd.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/UITableViewController-YvC-vN-mSd.nib
new file mode 100644
index 00000000..fefdbf3d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/UITableViewController-YvC-vN-mSd.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/YvC-vN-mSd-view-Udh-X7-hOc.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/YvC-vN-mSd-view-Udh-X7-hOc.nib
new file mode 100644
index 00000000..34446e22
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ActivityIndicatorViewController.storyboardc/YvC-vN-mSd-view-Udh-X7-hOc.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..cb435578
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/UITableViewController-Va4-Ge-jQn.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/UITableViewController-Va4-Ge-jQn.nib
new file mode 100644
index 00000000..f57a6a22
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/UITableViewController-Va4-Ge-jQn.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Va4-Ge-jQn-view-iro-ev-0xV.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Va4-Ge-jQn-view-iro-ev-0xV.nib
new file mode 100644
index 00000000..1951ed25
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/AlertControllerViewController.storyboardc/Va4-Ge-jQn-view-iro-ev-0xV.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..4144edf2
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/UITableViewController-gl0-hM-EWg.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/UITableViewController-gl0-hM-EWg.nib
new file mode 100644
index 00000000..e72fe7fa
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/UITableViewController-gl0-hM-EWg.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/gl0-hM-EWg-view-gDs-OX-aHt.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/gl0-hM-EWg-view-gDs-OX-aHt.nib
new file mode 100644
index 00000000..4509cd78
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ButtonViewController.storyboardc/gl0-hM-EWg-view-gDs-OX-aHt.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Credits.rtf b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Credits.rtf
new file mode 100644
index 00000000..b0ce7b86
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Credits.rtf
@@ -0,0 +1,9 @@
+{\rtf1\ansi\ansicpg1252\cocoartf2467
+\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
+{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
+{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;}
+\vieww9000\viewh8400\viewkind0
+\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\qc\partightenfactor0
+
+\f0\fs20 \cf2 Demonstrates how to use UIKit's views and controls.\
+}
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/7Xn-ho-KP8-view-LFl-gd-u3P.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/7Xn-ho-KP8-view-LFl-gd-u3P.nib
new file mode 100644
index 00000000..515db5b6
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/7Xn-ho-KP8-view-LFl-gd-u3P.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/Info.plist
new file mode 100644
index 00000000..8a521b05
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/UIViewController-7Xn-ho-KP8.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/UIViewController-7Xn-ho-KP8.nib
new file mode 100644
index 00000000..93906aa1
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/DatePickerController.storyboardc/UIViewController-7Xn-ho-KP8.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..6867c960
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/UIViewController-XCI-A9-c2M.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/UIViewController-XCI-A9-c2M.nib
new file mode 100644
index 00000000..457d38c0
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/UIViewController-XCI-A9-c2M.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/XCI-A9-c2M-view-InE-1J-uPb.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/XCI-A9-c2M-view-InE-1J-uPb.nib
new file mode 100644
index 00000000..56193b90
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ImageViewController.storyboardc/XCI-A9-c2M-view-InE-1J-uPb.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/InfoPlist.strings b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/InfoPlist.strings
new file mode 100644
index 00000000..c9cf3b13
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/InfoPlist.strings differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Axx-hg-9Xm-view-Bd8-dr-7ve.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Axx-hg-9Xm-view-Bd8-dr-7ve.nib
new file mode 100644
index 00000000..91a2a6d6
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Axx-hg-9Xm-view-Bd8-dr-7ve.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Info.plist
new file mode 100644
index 00000000..0ba4d0e5
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/UINavigationController-4yX-ry-qSy.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/UINavigationController-4yX-ry-qSy.nib
new file mode 100644
index 00000000..7283d227
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/LaunchScreen.storyboardc/UINavigationController-4yX-ry-qSy.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Localizable.strings b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Localizable.strings
new file mode 100644
index 00000000..88756d2b
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Localizable.strings differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/GgB-cT-22O-view-aE8-Eb-ul8.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/GgB-cT-22O-view-aE8-Eb-ul8.nib
new file mode 100644
index 00000000..438e6018
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/GgB-cT-22O-view-aE8-Eb-ul8.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/Info.plist
new file mode 100644
index 00000000..8eed473d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/MasterViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/MasterViewController.nib
new file mode 100644
index 00000000..2c311abf
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/MasterViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/initialDetail.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/initialDetail.nib
new file mode 100644
index 00000000..11665597
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/initialDetail.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/ioe-is-9Fo-view-Ie1-Wu-iah.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/ioe-is-9Fo-view-Ie1-Wu-iah.nib
new file mode 100644
index 00000000..ca0325b9
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/ioe-is-9Fo-view-Ie1-Wu-iah.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/navInitialDetail.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/navInitialDetail.nib
new file mode 100644
index 00000000..d66620c5
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/navInitialDetail.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/splitView.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/splitView.nib
new file mode 100644
index 00000000..b6350f1a
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/Main.storyboardc/splitView.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..b36b891e
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/UIViewController-ZSF-lM-gQa.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/UIViewController-ZSF-lM-gQa.nib
new file mode 100644
index 00000000..77ed65d1
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/UIViewController-ZSF-lM-gQa.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/ZSF-lM-gQa-view-1Df-6J-Q8v.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/ZSF-lM-gQa-view-1Df-6J-Q8v.nib
new file mode 100644
index 00000000..2b363e22
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PageControlViewController.storyboardc/ZSF-lM-gQa-view-1Df-6J-Q8v.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..b9834972
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/UIViewController-hIc-I2-PiV.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/UIViewController-hIc-I2-PiV.nib
new file mode 100644
index 00000000..93b86295
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/UIViewController-hIc-I2-PiV.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/hIc-I2-PiV-view-EB5-Ny-mbq.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/hIc-I2-PiV-view-EB5-Ny-mbq.nib
new file mode 100644
index 00000000..5e16a7eb
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/PickerViewController.storyboardc/hIc-I2-PiV-view-EB5-Ny-mbq.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..40b538e8
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/UITableViewController-aY0-FD-8DD.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/UITableViewController-aY0-FD-8DD.nib
new file mode 100644
index 00000000..32c6617d
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/UITableViewController-aY0-FD-8DD.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/aY0-FD-8DD-view-vxe-YC-yBi.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/aY0-FD-8DD-view-vxe-YC-yBi.nib
new file mode 100644
index 00000000..285171d2
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ProgressViewController.storyboardc/aY0-FD-8DD-view-vxe-YC-yBi.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/CustomSearchBarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/CustomSearchBarViewController.nib
new file mode 100644
index 00000000..fb3fc0e1
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/CustomSearchBarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/DefaultSearchBarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/DefaultSearchBarViewController.nib
new file mode 100644
index 00000000..bedcee6e
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/DefaultSearchBarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Info.plist
new file mode 100644
index 00000000..7911d1b6
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Mhd-Bs-sIn-view-YVy-et-UAQ.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Mhd-Bs-sIn-view-YVy-et-UAQ.nib
new file mode 100644
index 00000000..40724472
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Mhd-Bs-sIn-view-YVy-et-UAQ.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Search.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Search.nib
new file mode 100644
index 00000000..c39bcd00
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Search.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchBarEmbedInNavBarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchBarEmbedInNavBarViewController.nib
new file mode 100644
index 00000000..327d5443
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchBarEmbedInNavBarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchResultsViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchResultsViewController.nib
new file mode 100644
index 00000000..f899af42
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/SearchResultsViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Thx-B6-QkK-view-QvM-3S-GbD.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Thx-B6-QkK-view-QvM-3S-GbD.nib
new file mode 100644
index 00000000..39035f15
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/Thx-B6-QkK-view-QvM-3S-GbD.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aRM-gX-SK9-view-1PE-AW-QJq.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aRM-gX-SK9-view-1PE-AW-QJq.nib
new file mode 100644
index 00000000..4fc76a34
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aRM-gX-SK9-view-1PE-AW-QJq.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aTT-8g-UdL-view-VZF-3b-rcm.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aTT-8g-UdL-view-VZF-3b-rcm.nib
new file mode 100644
index 00000000..5a5b87a3
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/aTT-8g-UdL-view-VZF-3b-rcm.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/v21-vF-FLh-view-d2N-kr-XWw.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/v21-vF-FLh-view-d2N-kr-XWw.nib
new file mode 100644
index 00000000..b898576c
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SearchViewControllers.storyboardc/v21-vF-FLh-view-d2N-kr-XWw.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Eil-ie-nN6-view-fLQ-5f-tUh.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Eil-ie-nN6-view-fLQ-5f-tUh.nib
new file mode 100644
index 00000000..4014af9e
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Eil-ie-nN6-view-fLQ-5f-tUh.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..ea4defc8
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/UITableViewController-Eil-ie-nN6.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/UITableViewController-Eil-ie-nN6.nib
new file mode 100644
index 00000000..2def2c0a
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SegmentedControlViewController.storyboardc/UITableViewController-Eil-ie-nN6.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..5e516eed
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/UITableViewController-laz-6N-ZhE.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/UITableViewController-laz-6N-ZhE.nib
new file mode 100644
index 00000000..0ac7763b
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/UITableViewController-laz-6N-ZhE.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/laz-6N-ZhE-view-8xG-xW-Mvc.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/laz-6N-ZhE-view-8xG-xW-Mvc.nib
new file mode 100644
index 00000000..8ebf6c17
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SliderViewController.storyboardc/laz-6N-ZhE-view-8xG-xW-Mvc.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..fb04e8cb
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/K8w-Uq-R9J-view-Hwb-09-b4P.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/K8w-Uq-R9J-view-Hwb-09-b4P.nib
new file mode 100644
index 00000000..0676c015
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/K8w-Uq-R9J-view-Hwb-09-b4P.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/UIViewController-K8w-Uq-R9J.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/UIViewController-K8w-Uq-R9J.nib
new file mode 100644
index 00000000..4be23618
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StackViewController.storyboardc/UIViewController-K8w-Uq-R9J.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..487dcdba
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Ob2-pp-aCj-view-aQ3-9F-Tmi.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Ob2-pp-aCj-view-aQ3-9F-Tmi.nib
new file mode 100644
index 00000000..99fdb82f
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/Ob2-pp-aCj-view-aQ3-9F-Tmi.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/UITableViewController-Ob2-pp-aCj.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/UITableViewController-Ob2-pp-aCj.nib
new file mode 100644
index 00000000..9f1b4345
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/StepperViewController.storyboardc/UITableViewController-Ob2-pp-aCj.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..37a092d0
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/UITableViewController-zcI-oN-J3j.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/UITableViewController-zcI-oN-J3j.nib
new file mode 100644
index 00000000..a036d514
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/UITableViewController-zcI-oN-J3j.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/zcI-oN-J3j-view-4ER-nG-feZ.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/zcI-oN-J3j-view-4ER-nG-feZ.nib
new file mode 100644
index 00000000..cdc1e67e
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/SwitchViewController.storyboardc/zcI-oN-J3j-view-4ER-nG-feZ.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/DSJ-7r-oCY-view-dyj-uS-k8j.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/DSJ-7r-oCY-view-dyj-uS-k8j.nib
new file mode 100644
index 00000000..2ee82ace
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/DSJ-7r-oCY-view-dyj-uS-k8j.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..91e44b71
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/UITableViewController-DSJ-7r-oCY.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/UITableViewController-DSJ-7r-oCY.nib
new file mode 100644
index 00000000..05228b1a
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextFieldViewController.storyboardc/UITableViewController-DSJ-7r-oCY.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..93679b30
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/UIViewController-pUP-b0-VMf.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/UIViewController-pUP-b0-VMf.nib
new file mode 100644
index 00000000..f2e2facd
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/UIViewController-pUP-b0-VMf.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/pUP-b0-VMf-view-eAJ-am-dgQ.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/pUP-b0-VMf-view-eAJ-am-dgQ.nib
new file mode 100644
index 00000000..3cb520a3
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/TextViewController.storyboardc/pUP-b0-VMf-view-eAJ-am-dgQ.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/CustomToolbarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/CustomToolbarViewController.nib
new file mode 100644
index 00000000..2bec495a
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/CustomToolbarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/DefaultToolbarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/DefaultToolbarViewController.nib
new file mode 100644
index 00000000..650a901b
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/DefaultToolbarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/FY6-YQ-KUW-view-cQQ-vC-cql.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/FY6-YQ-KUW-view-cQQ-vC-cql.nib
new file mode 100644
index 00000000..1d44a2b1
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/FY6-YQ-KUW-view-cQQ-vC-cql.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Info.plist
new file mode 100644
index 00000000..8aad2f64
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/P5B-ej-GR8-view-lTJ-Dz-yrG.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/P5B-ej-GR8-view-lTJ-Dz-yrG.nib
new file mode 100644
index 00000000..97948f88
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/P5B-ej-GR8-view-lTJ-Dz-yrG.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/TintedToolbarViewController.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/TintedToolbarViewController.nib
new file mode 100644
index 00000000..1039b1f9
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/TintedToolbarViewController.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Toolbars.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Toolbars.nib
new file mode 100644
index 00000000..8d437082
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/Toolbars.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/c6p-Xx-oIp-view-LTn-gr-hZ8.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/c6p-Xx-oIp-view-LTn-gr-hZ8.nib
new file mode 100644
index 00000000..069185df
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/c6p-Xx-oIp-view-LTn-gr-hZ8.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/cTo-Y6-RL4-view-YY9-uv-rey.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/cTo-Y6-RL4-view-YY9-uv-rey.nib
new file mode 100644
index 00000000..13b99049
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/ToolbarViewControllers.storyboardc/cTo-Y6-RL4-view-YY9-uv-rey.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/Info.plist
new file mode 100644
index 00000000..97b1f641
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/UIViewController-i9U-A8-mkf.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/UIViewController-i9U-A8-mkf.nib
new file mode 100644
index 00000000..70580698
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/UIViewController-i9U-A8-mkf.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/i9U-A8-mkf-view-cde-Ag-lVB.nib b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/i9U-A8-mkf-view-cde-Ag-lVB.nib
new file mode 100644
index 00000000..ea78fc8b
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/WebViewController.storyboardc/i9U-A8-mkf-view-cde-Ag-lVB.nib differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/content.html b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/content.html
new file mode 100644
index 00000000..e424ba77
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Base.lproj/content.html
@@ -0,0 +1,15 @@
+
+
+
+ WKWebView
+
+
+
+
+ This is HTML content inside a WKWebView.
+
+
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Info.plist b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Info.plist
new file mode 100644
index 00000000..7c07542e
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/Info.plist differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/PkgInfo b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/PkgInfo
new file mode 100644
index 00000000..bd04210f
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/PkgInfo
@@ -0,0 +1 @@
+APPL????
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/UIKitCatalog b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/UIKitCatalog
new file mode 100644
index 00000000..4eca075a
Binary files /dev/null and b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/UIKitCatalog differ
diff --git a/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/_CodeSignature/CodeResources b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/_CodeSignature/CodeResources
new file mode 100644
index 00000000..c77b9eee
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/UIKitCatalog-iphonesimulator.app/_CodeSignature/CodeResources
@@ -0,0 +1,1019 @@
+
+
+
+
+ files
+
+ Assets.car
+
+ fISZf9xby649CtYmEdNupzuVdIA=
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/Info.plist
+
+ lrUR48NoTekvRV8AsNNqY1CnK40=
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/UITableViewController-YvC-vN-mSd.nib
+
+ OwkLwV7vdu6mUD1JL7mNlVznohQ=
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/YvC-vN-mSd-view-Udh-X7-hOc.nib
+
+ 0TkY7XwvDxciQOEV49BZqOKsj2s=
+
+ Base.lproj/AlertControllerViewController.storyboardc/Info.plist
+
+ YtChmQ/NiOl4CB/fMVSxejl9u1Y=
+
+ Base.lproj/AlertControllerViewController.storyboardc/UITableViewController-Va4-Ge-jQn.nib
+
+ 3mnUpYQM5jfaDYsqem3zoyHqL2E=
+
+ Base.lproj/AlertControllerViewController.storyboardc/Va4-Ge-jQn-view-iro-ev-0xV.nib
+
+ jpDVRr/QweVxk/JRodMfTAoPUyE=
+
+ Base.lproj/ButtonViewController.storyboardc/Info.plist
+
+ KJYq7qtvxNEukQboK8xGo9JmvHk=
+
+ Base.lproj/ButtonViewController.storyboardc/UITableViewController-gl0-hM-EWg.nib
+
+ Z/ko4z4ZrnPm6zMUcXlNhVHmbfE=
+
+ Base.lproj/ButtonViewController.storyboardc/gl0-hM-EWg-view-gDs-OX-aHt.nib
+
+ doS3yO+bJCz2yt/fZwXuOqHOido=
+
+ Base.lproj/Credits.rtf
+
+ i+g4kgfhviOOXQQfgWO6ha23MoM=
+
+ Base.lproj/DatePickerController.storyboardc/7Xn-ho-KP8-view-LFl-gd-u3P.nib
+
+ T3Jj7D7kE3UkTp44HAhErvw2Cr4=
+
+ Base.lproj/DatePickerController.storyboardc/Info.plist
+
+ WlyCwo8QJjnItogmeSU+ij3A4SE=
+
+ Base.lproj/DatePickerController.storyboardc/UIViewController-7Xn-ho-KP8.nib
+
+ y5Kw0pT/RJz++6gl9QpSYiw1SJ4=
+
+ Base.lproj/ImageViewController.storyboardc/Info.plist
+
+ RBSN6uazV8zFL3JebZfrYveER1A=
+
+ Base.lproj/ImageViewController.storyboardc/UIViewController-XCI-A9-c2M.nib
+
+ 4P5h7TTQi6IZlrUcJW39CPYKBM4=
+
+ Base.lproj/ImageViewController.storyboardc/XCI-A9-c2M-view-InE-1J-uPb.nib
+
+ ak40sfAsGkuxPzNFyOSIg3DqcVw=
+
+ Base.lproj/InfoPlist.strings
+
+ +7Bbe4Nsv1xIkOM2laZ15hG162Y=
+
+ Base.lproj/LaunchScreen.storyboardc/Axx-hg-9Xm-view-Bd8-dr-7ve.nib
+
+ aHDzkBvrhmTZNy59Nyko4hzT/zE=
+
+ Base.lproj/LaunchScreen.storyboardc/Info.plist
+
+ AXSuH0pzP/ZofxuvEaIAibqRZzo=
+
+ Base.lproj/LaunchScreen.storyboardc/UINavigationController-4yX-ry-qSy.nib
+
+ 7zYJZSvTsNrc62aicfGxOGAqKs0=
+
+ Base.lproj/Localizable.strings
+
+ AVUTDH0SKXuj2RzimB7pXaj1DAs=
+
+ Base.lproj/Main.storyboardc/GgB-cT-22O-view-aE8-Eb-ul8.nib
+
+ cXElEV9lySXXNAqv9zjzHGVt79M=
+
+ Base.lproj/Main.storyboardc/Info.plist
+
+ lWkLOzus34RdTou0hQ3wGmz3uMo=
+
+ Base.lproj/Main.storyboardc/MasterViewController.nib
+
+ VX3PeCoXaJS9fl69HZB5FsGqPkE=
+
+ Base.lproj/Main.storyboardc/initialDetail.nib
+
+ lvhDVXPuP1WXHconP4z50HO3rtw=
+
+ Base.lproj/Main.storyboardc/ioe-is-9Fo-view-Ie1-Wu-iah.nib
+
+ 8X9FkKNc1OUfeP9uU8dVgGy0HPA=
+
+ Base.lproj/Main.storyboardc/navInitialDetail.nib
+
+ vibstbGi/oVyW2I1qd/hiZa7hCM=
+
+ Base.lproj/Main.storyboardc/splitView.nib
+
+ NE2jq/bXbsavgq3o0i2a02d0JHs=
+
+ Base.lproj/PageControlViewController.storyboardc/Info.plist
+
+ ERny0hx+vYPk1raNb9/LuJPlpCo=
+
+ Base.lproj/PageControlViewController.storyboardc/UIViewController-ZSF-lM-gQa.nib
+
+ ydYsg6amdknZhtGF1ZCJVAAU1TA=
+
+ Base.lproj/PageControlViewController.storyboardc/ZSF-lM-gQa-view-1Df-6J-Q8v.nib
+
+ ZxUciDiZD73HjJX4fPk8V7Ah264=
+
+ Base.lproj/PickerViewController.storyboardc/Info.plist
+
+ 8oQTd+rVvHsNIiitqlkBTiAgemU=
+
+ Base.lproj/PickerViewController.storyboardc/UIViewController-hIc-I2-PiV.nib
+
+ /PEV7sZkM7B+rM69LeVhQmgT0ik=
+
+ Base.lproj/PickerViewController.storyboardc/hIc-I2-PiV-view-EB5-Ny-mbq.nib
+
+ eY6NryOX9GgXAZSp4r6pfDmM4/Q=
+
+ Base.lproj/ProgressViewController.storyboardc/Info.plist
+
+ pl5JQf0K4UidB81otx5t1y0L8lw=
+
+ Base.lproj/ProgressViewController.storyboardc/UITableViewController-aY0-FD-8DD.nib
+
+ AFeqGgjLawW06/xqWsoVmn2R88g=
+
+ Base.lproj/ProgressViewController.storyboardc/aY0-FD-8DD-view-vxe-YC-yBi.nib
+
+ 4tIcYfG/Qei+XXJYFayo7OHmJNk=
+
+ Base.lproj/SearchViewControllers.storyboardc/CustomSearchBarViewController.nib
+
+ V7fo2jUu4Fj99tfPtmKIgGbLmzg=
+
+ Base.lproj/SearchViewControllers.storyboardc/DefaultSearchBarViewController.nib
+
+ mODpZ79VZrmBBjcQktlsu2vriM4=
+
+ Base.lproj/SearchViewControllers.storyboardc/Info.plist
+
+ MSm5VipzANVqHhmJcsDoD31yUr4=
+
+ Base.lproj/SearchViewControllers.storyboardc/Mhd-Bs-sIn-view-YVy-et-UAQ.nib
+
+ GxKDK48mSnyf3iuPZLwpvV/0OiA=
+
+ Base.lproj/SearchViewControllers.storyboardc/Search.nib
+
+ haGzk2rREbyDDR5GhCQ9HZH28cA=
+
+ Base.lproj/SearchViewControllers.storyboardc/SearchBarEmbedInNavBarViewController.nib
+
+ DXoQ7V6htJopZv7iozWJx/rdLqk=
+
+ Base.lproj/SearchViewControllers.storyboardc/SearchResultsViewController.nib
+
+ Z+UMlF91GFwXWWH8VDg3CzYimwo=
+
+ Base.lproj/SearchViewControllers.storyboardc/Thx-B6-QkK-view-QvM-3S-GbD.nib
+
+ prs9Ax34VMTT1f9ohBIydWxKklI=
+
+ Base.lproj/SearchViewControllers.storyboardc/aRM-gX-SK9-view-1PE-AW-QJq.nib
+
+ +tcAfHe1RFIRcj0slBozsRyFBiM=
+
+ Base.lproj/SearchViewControllers.storyboardc/aTT-8g-UdL-view-VZF-3b-rcm.nib
+
+ T/TzKQPcfxZOm1EJ67On/YjNGQI=
+
+ Base.lproj/SearchViewControllers.storyboardc/v21-vF-FLh-view-d2N-kr-XWw.nib
+
+ WvsjPtFU0WxY45rYnWluZT3bctc=
+
+ Base.lproj/SegmentedControlViewController.storyboardc/Eil-ie-nN6-view-fLQ-5f-tUh.nib
+
+ lgIVzkrB4TKGwu8g7O/poCPWK8M=
+
+ Base.lproj/SegmentedControlViewController.storyboardc/Info.plist
+
+ TR1rLqPvOhqWRulfEPM/G0P6YNE=
+
+ Base.lproj/SegmentedControlViewController.storyboardc/UITableViewController-Eil-ie-nN6.nib
+
+ PD2VuRrICIwa1U4yyMZ/GfpP6yA=
+
+ Base.lproj/SliderViewController.storyboardc/Info.plist
+
+ WYIV4FeKktIoA0tJojwPS69KmfE=
+
+ Base.lproj/SliderViewController.storyboardc/UITableViewController-laz-6N-ZhE.nib
+
+ vLBA2O/21vY9PLfgejQE0xTNl7U=
+
+ Base.lproj/SliderViewController.storyboardc/laz-6N-ZhE-view-8xG-xW-Mvc.nib
+
+ qGXkgGkXCQADHkc9J5+JbBBguIU=
+
+ Base.lproj/StackViewController.storyboardc/Info.plist
+
+ 5oqAkvU2E+YXY5uDrCnJ1aGZr8I=
+
+ Base.lproj/StackViewController.storyboardc/K8w-Uq-R9J-view-Hwb-09-b4P.nib
+
+ 6Wd+9tR1gS6Ac4pOGaUh1gDTKH8=
+
+ Base.lproj/StackViewController.storyboardc/UIViewController-K8w-Uq-R9J.nib
+
+ 4KY/RiIg7SQBgFeQb24Hg0EzlPI=
+
+ Base.lproj/StepperViewController.storyboardc/Info.plist
+
+ BIx8/h5MOPXZr7+7/qdhfVn/prU=
+
+ Base.lproj/StepperViewController.storyboardc/Ob2-pp-aCj-view-aQ3-9F-Tmi.nib
+
+ jFoPO9aA4OPWXKNpFBjDUvKOHwo=
+
+ Base.lproj/StepperViewController.storyboardc/UITableViewController-Ob2-pp-aCj.nib
+
+ m0DooNwShMQI2md4OBna6Dh0pWg=
+
+ Base.lproj/SwitchViewController.storyboardc/Info.plist
+
+ n0co21oRiXxqW2/ZAU9cBQNJ/9o=
+
+ Base.lproj/SwitchViewController.storyboardc/UITableViewController-zcI-oN-J3j.nib
+
+ LFw4a6JHpcAWLjHLz97zzdsde4g=
+
+ Base.lproj/SwitchViewController.storyboardc/zcI-oN-J3j-view-4ER-nG-feZ.nib
+
+ KOVThYVzJyoJPUF/R/4ocGb8QR8=
+
+ Base.lproj/TextFieldViewController.storyboardc/DSJ-7r-oCY-view-dyj-uS-k8j.nib
+
+ vpP1y63JOy3SIrkXKdtdJl+Pdd0=
+
+ Base.lproj/TextFieldViewController.storyboardc/Info.plist
+
+ +y9mmC1kWGQELzp2OvNdOesdqXE=
+
+ Base.lproj/TextFieldViewController.storyboardc/UITableViewController-DSJ-7r-oCY.nib
+
+ zOO7PpSlC/XvvHfUajpxeM8+lko=
+
+ Base.lproj/TextViewController.storyboardc/Info.plist
+
+ 6A4BHxk34QZjcSza9I9oWyt1Glw=
+
+ Base.lproj/TextViewController.storyboardc/UIViewController-pUP-b0-VMf.nib
+
+ BDJUntpKC1M91nMoqJM7J1FOt3Y=
+
+ Base.lproj/TextViewController.storyboardc/pUP-b0-VMf-view-eAJ-am-dgQ.nib
+
+ HobsgDYZ/OaqyTDh4oUCDQ6TGp0=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/CustomToolbarViewController.nib
+
+ sIBGr6mNoHamgefpC0XWUeor8RU=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/DefaultToolbarViewController.nib
+
+ s7P6IadjyPkVNPtTJC53xqIxIwc=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/FY6-YQ-KUW-view-cQQ-vC-cql.nib
+
+ wIY7H6RkeSo1fu2gUOaykS0Xnbs=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/Info.plist
+
+ tk/8bPgyB9exBHhWPgph8minIpo=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/P5B-ej-GR8-view-lTJ-Dz-yrG.nib
+
+ EMynlfEAwDSUcXQfZhY5S21LWbc=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/TintedToolbarViewController.nib
+
+ TCzfRKFtoRHf/Uy/tp86iJe9oQw=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/Toolbars.nib
+
+ 2kawhtyzHzG3DAdKKWqQV0qx0VE=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/c6p-Xx-oIp-view-LTn-gr-hZ8.nib
+
+ VTDupVDB5Jm9YRugoX2NiSyDkJo=
+
+ Base.lproj/ToolbarViewControllers.storyboardc/cTo-Y6-RL4-view-YY9-uv-rey.nib
+
+ ymhj2XtTg1Pd4dzFwz3YLsICeUU=
+
+ Base.lproj/WebViewController.storyboardc/Info.plist
+
+ 2+CGBtQ9tr99CtsVdgQghdI6S40=
+
+ Base.lproj/WebViewController.storyboardc/UIViewController-i9U-A8-mkf.nib
+
+ uhABOk0uV+vPBhuUdUGi3yDYfZQ=
+
+ Base.lproj/WebViewController.storyboardc/i9U-A8-mkf-view-cde-Ag-lVB.nib
+
+ dUr2xK/JP1u064oXeYbKYGPXxHw=
+
+ Base.lproj/content.html
+
+ MIyjarWD9sYxtr6vtFanKGEgjwM=
+
+ Info.plist
+
+ 6E5LMvlwrKSOfinxDg8vHp1VY/s=
+
+ PkgInfo
+
+ n57qDP4tZfLD1rCS43W0B4LQjzE=
+
+
+ files2
+
+ Assets.car
+
+ hash2
+
+ WK+URF6Ef2pqL1K0Fs1wRtK8AJeCihIaig/SawSD8gg=
+
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/Info.plist
+
+ hash2
+
+ xEFqAwHDKuHxFGABbqoEwxdRNWR9L64ZIxXtYsTJgRU=
+
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/UITableViewController-YvC-vN-mSd.nib
+
+ hash2
+
+ /ujizbSONhhj1E3FGzAmz0PNFni+3pFu41UJNN4jeUQ=
+
+
+ Base.lproj/ActivityIndicatorViewController.storyboardc/YvC-vN-mSd-view-Udh-X7-hOc.nib
+
+ hash2
+
+ Ow4rUtkgorj/Fnja6M57DMAftsneKOZ3F+Lz4QE4vjc=
+
+
+ Base.lproj/AlertControllerViewController.storyboardc/Info.plist
+
+ hash2
+
+ ylsKxxvwO4zTeOsY8RbzLJ8Z0+1Cm8M0xleFishRu3I=
+
+
+ Base.lproj/AlertControllerViewController.storyboardc/UITableViewController-Va4-Ge-jQn.nib
+
+ hash2
+
+ MI/aIORfyV7Vct5W4Yahvu88dBuoTVHGuTIs2xhieP8=
+
+
+ Base.lproj/AlertControllerViewController.storyboardc/Va4-Ge-jQn-view-iro-ev-0xV.nib
+
+ hash2
+
+ 0HhBZTfDoLiHebZmwzdwpGWUGONXcYZ4pLRpj2JbbbM=
+
+
+ Base.lproj/ButtonViewController.storyboardc/Info.plist
+
+ hash2
+
+ 65WLnBEMsKBtkbcasVEzUfkWZcA3OIjGo5nbBAX/CEU=
+
+
+ Base.lproj/ButtonViewController.storyboardc/UITableViewController-gl0-hM-EWg.nib
+
+ hash2
+
+ 0hrKBadL3EMIGFN0RXIm3U7CGbguQY0EZHXxXaPKBTA=
+
+
+ Base.lproj/ButtonViewController.storyboardc/gl0-hM-EWg-view-gDs-OX-aHt.nib
+
+ hash2
+
+ GCdWQxTYQ169NsXxU+9WO+NTWmTvyYotuNaR+M6bUGg=
+
+
+ Base.lproj/Credits.rtf
+
+ hash2
+
+ BMqUzs1mNPgZo2NCDQmqAxowCJ0egjoh6k8tnXVnZLI=
+
+
+ Base.lproj/DatePickerController.storyboardc/7Xn-ho-KP8-view-LFl-gd-u3P.nib
+
+ hash2
+
+ 5bpBEv7RGYSmYJaJCN3NXDAartiZm1Gksbkr3ONTBps=
+
+
+ Base.lproj/DatePickerController.storyboardc/Info.plist
+
+ hash2
+
+ I1eeD/tMER2IWsqhFH21jVwBdoCRaA8MF7aZTg1oJIs=
+
+
+ Base.lproj/DatePickerController.storyboardc/UIViewController-7Xn-ho-KP8.nib
+
+ hash2
+
+ 95h1oECT6HU/37DN6TR16X2LVwg9qEEmIw0xWFdq3AA=
+
+
+ Base.lproj/ImageViewController.storyboardc/Info.plist
+
+ hash2
+
+ OD+k56v4QKOa5nwXrUIG4lysX/WQrig9Lj5SqGHEqkM=
+
+
+ Base.lproj/ImageViewController.storyboardc/UIViewController-XCI-A9-c2M.nib
+
+ hash2
+
+ FwT+yGg7i+01nn7iYvfroibtqOeUG+9IC2XL6BTlXOs=
+
+
+ Base.lproj/ImageViewController.storyboardc/XCI-A9-c2M-view-InE-1J-uPb.nib
+
+ hash2
+
+ dE84+pEQeRiDMLhGrsTzlIiJHsSN3BRybuK3xZwywcs=
+
+
+ Base.lproj/InfoPlist.strings
+
+ hash2
+
+ U0CT4EbhruOUgfFgR4ApjSJgroiJG1CrieHYA7EBiNs=
+
+
+ Base.lproj/LaunchScreen.storyboardc/Axx-hg-9Xm-view-Bd8-dr-7ve.nib
+
+ hash2
+
+ ccllIi71bsue/2KdqYKgOjh77Hny1MFBH7FlgnaFqPY=
+
+
+ Base.lproj/LaunchScreen.storyboardc/Info.plist
+
+ hash2
+
+ GYY3ma8Of9YVbuv3gLskSSr78xKOkwE7o+KW5s5tAeE=
+
+
+ Base.lproj/LaunchScreen.storyboardc/UINavigationController-4yX-ry-qSy.nib
+
+ hash2
+
+ 4GD9QbLOrCaMTyx1uyCwN7G4fNyfxcs50QSjbPbrSnM=
+
+
+ Base.lproj/Localizable.strings
+
+ hash2
+
+ np8HgGGhbjRhxWZ6eLIs3XN55dhGdXet03AKYRxTQxo=
+
+
+ Base.lproj/Main.storyboardc/GgB-cT-22O-view-aE8-Eb-ul8.nib
+
+ hash2
+
+ 4ubhTej0UBPSgvIEpkzItNEr9+vpEI7f8BgDKKi7JIA=
+
+
+ Base.lproj/Main.storyboardc/Info.plist
+
+ hash2
+
+ dpUQNtz6KvuEkDMWNpvQ6wlF5W3AhYrUUhzBvG/HQsE=
+
+
+ Base.lproj/Main.storyboardc/MasterViewController.nib
+
+ hash2
+
+ s+TusSk/UecT79oWQNODadVAdl+iGMOXUC7uI3a0ksg=
+
+
+ Base.lproj/Main.storyboardc/initialDetail.nib
+
+ hash2
+
+ B/9WMGLHV1jgcv5wSUHxf32DK+jND0gg4PoxkkMRlu0=
+
+
+ Base.lproj/Main.storyboardc/ioe-is-9Fo-view-Ie1-Wu-iah.nib
+
+ hash2
+
+ 1d77NU8jRsN2SdEwGFhma/H9MCn76GXLfj//XnIPgto=
+
+
+ Base.lproj/Main.storyboardc/navInitialDetail.nib
+
+ hash2
+
+ 2XExbFEV3BuRsXO4IKpwJnmFFx9OJpRm3QW9FvSwlws=
+
+
+ Base.lproj/Main.storyboardc/splitView.nib
+
+ hash2
+
+ JeFZfM6ovnPAI6gIky2+QXP7P0F2aWIz/iG1S2tDYYk=
+
+
+ Base.lproj/PageControlViewController.storyboardc/Info.plist
+
+ hash2
+
+ 0DlipnZFR2/6LjR8l4RuUPxHjE0a6tDooT/zL2qDoeU=
+
+
+ Base.lproj/PageControlViewController.storyboardc/UIViewController-ZSF-lM-gQa.nib
+
+ hash2
+
+ +nLYfsr1wWAfSlvucQues1PpFwixl981Zt4e64rHhy8=
+
+
+ Base.lproj/PageControlViewController.storyboardc/ZSF-lM-gQa-view-1Df-6J-Q8v.nib
+
+ hash2
+
+ ixf8PXW2epNUdtJlo1D7T7DftvsYDTVKEdwdUDm3+cY=
+
+
+ Base.lproj/PickerViewController.storyboardc/Info.plist
+
+ hash2
+
+ StV5Ilr7RaSl2ggv2yylwGZ53bnN8VQaG1YM+82WbM8=
+
+
+ Base.lproj/PickerViewController.storyboardc/UIViewController-hIc-I2-PiV.nib
+
+ hash2
+
+ fir8nw4Tsj2pRK5mJfjosaiuxipmftpTBra3Hs2IKQw=
+
+
+ Base.lproj/PickerViewController.storyboardc/hIc-I2-PiV-view-EB5-Ny-mbq.nib
+
+ hash2
+
+ LKJozJzHnxuXPBcPn4GAw1TQzcJ1p+JpU+P1a/A29kk=
+
+
+ Base.lproj/ProgressViewController.storyboardc/Info.plist
+
+ hash2
+
+ t4MHaGZZ2bfZ7h0Eq5z9WIBCGcnmZtrH7Fsn/gZde7s=
+
+
+ Base.lproj/ProgressViewController.storyboardc/UITableViewController-aY0-FD-8DD.nib
+
+ hash2
+
+ bGVAmeU7myXWXavgA7aqH1x/iQmfucp5NzwlUP/jpyM=
+
+
+ Base.lproj/ProgressViewController.storyboardc/aY0-FD-8DD-view-vxe-YC-yBi.nib
+
+ hash2
+
+ TMcFaVQCW3RECM9I4MCd+oqb9k7fb2Wlr60Yr6vo/+A=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/CustomSearchBarViewController.nib
+
+ hash2
+
+ 7FJpLH4mFYCWewFTuxr9OKw/ofhIcZiX+AYtzWkTvxw=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/DefaultSearchBarViewController.nib
+
+ hash2
+
+ FpFCb/1NzfO0Vo8VoZRo2jfSFkvtDkwYyjBl1HDUruQ=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/Info.plist
+
+ hash2
+
+ KUCqI5LJ9JaUlKSl8+x+qZECWT4FOwaQ9VwnQXhDUS8=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/Mhd-Bs-sIn-view-YVy-et-UAQ.nib
+
+ hash2
+
+ PBc7rgv6EQ3tl1g6cfx5TBb12HnqZedd0fSrNm1B4R8=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/Search.nib
+
+ hash2
+
+ 55x9mKiXOVhWHzWyfPGnsP9VgjDF/NLCizA2aPuEoh0=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/SearchBarEmbedInNavBarViewController.nib
+
+ hash2
+
+ /FViYu7z3ZO0PATP2V+5zw4bBV/LnA2SRQAxwsW0LY8=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/SearchResultsViewController.nib
+
+ hash2
+
+ W95Cw5Tfr9l9115l1Jm1bAxr6sqtsecQSv1q86fslPQ=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/Thx-B6-QkK-view-QvM-3S-GbD.nib
+
+ hash2
+
+ qwVBwLXws1Q5Gae/mtSn14yVqghg62PiRLFsYYr4vnI=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/aRM-gX-SK9-view-1PE-AW-QJq.nib
+
+ hash2
+
+ zFExUsCNqg1phE/BqOa/se9DHwerodoZWluQEdEtQrc=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/aTT-8g-UdL-view-VZF-3b-rcm.nib
+
+ hash2
+
+ lp4am3dMWVUjHXn2bZkvbaEXagUyLLBfOevoxECS2Bk=
+
+
+ Base.lproj/SearchViewControllers.storyboardc/v21-vF-FLh-view-d2N-kr-XWw.nib
+
+ hash2
+
+ M9iHi8oIDvq1HcZqTizFKphZqsX4Wgix2Mk1KxLIM7E=
+
+
+ Base.lproj/SegmentedControlViewController.storyboardc/Eil-ie-nN6-view-fLQ-5f-tUh.nib
+
+ hash2
+
+ +fADaXaBN8JqFg8Dgh9TTZCPGjkSc82Ddqze5P2Y5i0=
+
+
+ Base.lproj/SegmentedControlViewController.storyboardc/Info.plist
+
+ hash2
+
+ FadMJyqvUjNZIspqkNCv9/2vdxZLK/IsHwHbfCzZpc8=
+
+
+ Base.lproj/SegmentedControlViewController.storyboardc/UITableViewController-Eil-ie-nN6.nib
+
+ hash2
+
+ eAN8BrepMyRIVZbh9CIUCY6rgzbpIYJFHmKKQGkvrSQ=
+
+
+ Base.lproj/SliderViewController.storyboardc/Info.plist
+
+ hash2
+
+ ttBfIWLxS0Q5sT+ogZe52Yn5apEJkOnexOM43AWRq5k=
+
+
+ Base.lproj/SliderViewController.storyboardc/UITableViewController-laz-6N-ZhE.nib
+
+ hash2
+
+ tc6YMZucWAWL13Gu5RHQuiGesnKhc3kX6uYEnBnGNic=
+
+
+ Base.lproj/SliderViewController.storyboardc/laz-6N-ZhE-view-8xG-xW-Mvc.nib
+
+ hash2
+
+ MrrK3k9mAO1EzNSZxsXZXhBZile9qzJq/Ih18LxTYwQ=
+
+
+ Base.lproj/StackViewController.storyboardc/Info.plist
+
+ hash2
+
+ cNzA35SgqdiuSDwlRzToZbs67RUxPy9OF+UVBd0lhQA=
+
+
+ Base.lproj/StackViewController.storyboardc/K8w-Uq-R9J-view-Hwb-09-b4P.nib
+
+ hash2
+
+ aHzLs5cTKrdFUKhkWZ1F0dDoUfwye9/6p2kmaBNxZC4=
+
+
+ Base.lproj/StackViewController.storyboardc/UIViewController-K8w-Uq-R9J.nib
+
+ hash2
+
+ 62+kvrj8fjvuW5uOL6V/HlkplRy4gL4PL1txc/94wv4=
+
+
+ Base.lproj/StepperViewController.storyboardc/Info.plist
+
+ hash2
+
+ AgGRT61Utbl8lHld7RWYXbOHW/fBhHXWAOkGtqQlfWI=
+
+
+ Base.lproj/StepperViewController.storyboardc/Ob2-pp-aCj-view-aQ3-9F-Tmi.nib
+
+ hash2
+
+ GQAS0+hS0+B411HU/1Oz2whbRcPiAnuek2HNzTixeK4=
+
+
+ Base.lproj/StepperViewController.storyboardc/UITableViewController-Ob2-pp-aCj.nib
+
+ hash2
+
+ Hy2c7tkjTElF52IgqH39AE40lTbjVIS6G9tV5hxgCMg=
+
+
+ Base.lproj/SwitchViewController.storyboardc/Info.plist
+
+ hash2
+
+ wcz4RoYHFlu+A1UlOjWoR1+WQfyy1Df/kqB+QB1htbk=
+
+
+ Base.lproj/SwitchViewController.storyboardc/UITableViewController-zcI-oN-J3j.nib
+
+ hash2
+
+ UhrmmU5V8rumCBmAQUQWZ3XtCSWhyZ8kr5geQL6rzaI=
+
+
+ Base.lproj/SwitchViewController.storyboardc/zcI-oN-J3j-view-4ER-nG-feZ.nib
+
+ hash2
+
+ NWeklQLM2HdPqRXIEqFI+z7XUn83Wlyj8uQINdK/ATE=
+
+
+ Base.lproj/TextFieldViewController.storyboardc/DSJ-7r-oCY-view-dyj-uS-k8j.nib
+
+ hash2
+
+ wPqwJsypIF46lrqrY+cFd8KmIYYGaOgnj8BVDjmo6Cc=
+
+
+ Base.lproj/TextFieldViewController.storyboardc/Info.plist
+
+ hash2
+
+ K/StPY7yXBr4zpRcLLp6dQQaYhfdgs8Qh/KL83iVeHE=
+
+
+ Base.lproj/TextFieldViewController.storyboardc/UITableViewController-DSJ-7r-oCY.nib
+
+ hash2
+
+ yHdAYmbDyjUjDAsRVPrLVgqtrkMUDj+FZ6CvPH041jE=
+
+
+ Base.lproj/TextViewController.storyboardc/Info.plist
+
+ hash2
+
+ 3aBL+a8HZHap9qpZaAB7cdAi8lGJFPKSwy6Fwe8aDe8=
+
+
+ Base.lproj/TextViewController.storyboardc/UIViewController-pUP-b0-VMf.nib
+
+ hash2
+
+ heUMBzR8Fb2E1v3CmojuYHAi2hGEnqyJEWvoTL1YsZk=
+
+
+ Base.lproj/TextViewController.storyboardc/pUP-b0-VMf-view-eAJ-am-dgQ.nib
+
+ hash2
+
+ W3Yj2l0hyUC63urYSQ3eyUH1MOedoNH/qE6L/cEmpik=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/CustomToolbarViewController.nib
+
+ hash2
+
+ V3LkoXBxNqjnIa63/fAGmLQjRnmhfbak3so/OMFyelg=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/DefaultToolbarViewController.nib
+
+ hash2
+
+ idkD4QW+oIFsH5Y5YXSNHSa/ySI4W/rGRYBDzfk8Ges=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/FY6-YQ-KUW-view-cQQ-vC-cql.nib
+
+ hash2
+
+ 5LTVzTgeXXoSA5EWsTsTRtKFF4yb8PQ1PfvOKW2nRB0=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/Info.plist
+
+ hash2
+
+ 6SS5A/yZBMFLZBXkmyF5+PkIvz2U4NRc7rkMhUJt+tc=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/P5B-ej-GR8-view-lTJ-Dz-yrG.nib
+
+ hash2
+
+ w68l7hYQacQhCXDdhWn9r2n16dl3VpbgdteSlaZmFro=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/TintedToolbarViewController.nib
+
+ hash2
+
+ aElmSVRmp3kcDRsbduj11OAXdGXG+thHPbkznSXNoAI=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/Toolbars.nib
+
+ hash2
+
+ hJuYi2KONSbZ/ISson+pIhQoPMFI+/hcnbAy5dceZxc=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/c6p-Xx-oIp-view-LTn-gr-hZ8.nib
+
+ hash2
+
+ ymxSKYvd/YOnTMRwi47fyBz3fXcwfsvGvCWLVux2DmQ=
+
+
+ Base.lproj/ToolbarViewControllers.storyboardc/cTo-Y6-RL4-view-YY9-uv-rey.nib
+
+ hash2
+
+ 0YMHQstCKruf4fc/TKJMz6leYl8/DPIBdX1v5VfYy6Y=
+
+
+ Base.lproj/WebViewController.storyboardc/Info.plist
+
+ hash2
+
+ Ksmve5mpWNHCIWQnvOQJJc1Suqz6OpAZuNJf1Z3TH3U=
+
+
+ Base.lproj/WebViewController.storyboardc/UIViewController-i9U-A8-mkf.nib
+
+ hash2
+
+ stA1lykSc0RReHkcQKpIHWKcQ8PJ2YinZJW7gt0+I+Y=
+
+
+ Base.lproj/WebViewController.storyboardc/i9U-A8-mkf-view-cde-Ag-lVB.nib
+
+ hash2
+
+ qWVdEHAqQHlaFXglbDueOoSZRLj7mPlOkYu/GuBkq1s=
+
+
+ Base.lproj/content.html
+
+ hash2
+
+ qZDxWF46M4S5s1t6WlK7C4i7HgIv9QJFKN5Qvdlcn/I=
+
+
+
+ rules
+
+ ^.*
+
+ ^.*\.lproj/
+
+ optional
+
+ weight
+ 1000
+
+ ^.*\.lproj/locversion.plist$
+
+ omit
+
+ weight
+ 1100
+
+ ^Base\.lproj/
+
+ weight
+ 1010
+
+ ^version.plist$
+
+
+ rules2
+
+ .*\.dSYM($|/)
+
+ weight
+ 11
+
+ ^(.*/)?\.DS_Store$
+
+ omit
+
+ weight
+ 2000
+
+ ^.*
+
+ ^.*\.lproj/
+
+ optional
+
+ weight
+ 1000
+
+ ^.*\.lproj/locversion.plist$
+
+ omit
+
+ weight
+ 1100
+
+ ^Base\.lproj/
+
+ weight
+ 1010
+
+ ^Info\.plist$
+
+ omit
+
+ weight
+ 20
+
+ ^PkgInfo$
+
+ omit
+
+ weight
+ 20
+
+ ^embedded\.provisionprofile$
+
+ weight
+ 20
+
+ ^version\.plist$
+
+ weight
+ 20
+
+
+
+
diff --git a/e2e/tests/mob.ios/assets/caps.js b/e2e/tests/mob.ios/assets/caps.js
new file mode 100644
index 00000000..1c37e518
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/caps.js
@@ -0,0 +1,11 @@
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/TestApp.app');
+
+module.exports = {
+ platformName: 'iOS',
+ automationName: 'XCUITest',
+ deviceName: process.env.deviceName,
+ platformVersion: process.env.platformVersion,
+ app: apkPath,
+ udid: process.env.udid
+};
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/assets/caps3.js b/e2e/tests/mob.ios/assets/caps3.js
new file mode 100644
index 00000000..652d6bfa
--- /dev/null
+++ b/e2e/tests/mob.ios/assets/caps3.js
@@ -0,0 +1,12 @@
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/UIKitCatalog-iphonesimulator.app');
+
+module.exports = {
+ platformName: 'iOS',
+ automationName: 'XCUITest',
+ deviceName: process.env.deviceName,
+ platformVersion: process.env.platformVersion,
+ app: apkPath,
+ udid: process.env.udid,
+ instrumentApp : true
+};
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.SauceGuineaPig.js b/e2e/tests/mob.ios/tests/mob.ios.SauceGuineaPig.js
new file mode 100644
index 00000000..41e132fa
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.SauceGuineaPig.js
@@ -0,0 +1,3 @@
+const caps2 = require('../assets/caps2');
+mob.init(caps2);
+
diff --git a/e2e/tests/mob.ios/tests/mob.ios.UIKitCatalog.js b/e2e/tests/mob.ios/tests/mob.ios.UIKitCatalog.js
new file mode 100644
index 00000000..c2c67217
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.UIKitCatalog.js
@@ -0,0 +1,3 @@
+const caps3 = require('../assets/caps3');
+mob.init(caps3);
+
diff --git a/e2e/tests/mob.ios/tests/mob.ios.alertAcceptPass.js b/e2e/tests/mob.ios/tests/mob.ios.alertAcceptPass.js
new file mode 100644
index 00000000..12a0d3e3
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.alertAcceptPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+mob.click('//XCUIElementTypeButton[@name="show alert"]');
+
+mob.pause(5000);
+
+mob.alertAccept();
+
+mob.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.alertDismissPass.js b/e2e/tests/mob.ios/tests/mob.ios.alertDismissPass.js
new file mode 100644
index 00000000..6e741f1f
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.alertDismissPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+mob.click('//XCUIElementTypeButton[@name="show alert"]');
+
+mob.pause(5000);
+
+mob.alertDismiss();
+
+mob.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.assertTextPass.js b/e2e/tests/mob.ios/tests/mob.ios.assertTextPass.js
new file mode 100644
index 00000000..5d84abac
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.assertTextPass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+const path = '//XCUIElementTypeStaticText[@name="Compute Sum"]';
+const expectedText = 'Compute Sum';
+
+const text = mob.getText(path);
+
+log.info(text);
+
+assert.equal(text, expectedText);
+
+mob.assertText(path, expectedText);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.assertValuePass.js b/e2e/tests/mob.ios/tests/mob.ios.assertValuePass.js
new file mode 100644
index 00000000..71990c7e
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.assertValuePass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+const path = '//XCUIElementTypeSlider[@name="AppElem"]';
+const expectedValue = '50%';
+
+const value = mob.getValue(path);
+
+log.info(value);
+
+assert.equal(value, expectedValue);
+
+mob.assertValue(path, expectedValue);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.clearPass.js b/e2e/tests/mob.ios/tests/mob.ios.clearPass.js
new file mode 100644
index 00000000..cc3d52b6
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.clearPass.js
@@ -0,0 +1,16 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+var el1 = mob.findElement('//XCUIElementTypeTextField[@name="IntegerA"]');
+mob.click(el1);
+
+mob.type(el1, '0544501591');
+
+mob.sendKeys('Enter');
+
+mob.pause(3000);
+
+mob.clear(el1);
+
+mob.pause(5000);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.clickLongPass.js b/e2e/tests/mob.ios/tests/mob.ios.clickLongPass.js
new file mode 100644
index 00000000..22113de0
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.clickLongPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+var el1 = mob.findElement('//XCUIElementTypeTextField[@name="IntegerA"]');
+mob.clickLong(el1, 5000);
+
+mob.pause(3000);
+
+mob.clickMultipleTimes(el1, 2);
+
+mob.pause(3000);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.disposePass.js b/e2e/tests/mob.ios/tests/mob.ios.disposePass.js
new file mode 100644
index 00000000..c0237672
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.disposePass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+mob.shake();
+mob.dispose();
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.findElementsPass.js b/e2e/tests/mob.ios/tests/mob.ios.findElementsPass.js
new file mode 100644
index 00000000..34db5846
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.findElementsPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+const elements = mob.findElements('//XCUIElementTypeStaticText[@name="AppElem"]');
+
+assert.equal(elements.length, 2);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getAlertTextPass.js b/e2e/tests/mob.ios/tests/mob.ios.getAlertTextPass.js
new file mode 100644
index 00000000..08b57b06
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getAlertTextPass.js
@@ -0,0 +1,16 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+mob.click('//XCUIElementTypeButton[@name="show alert"]');
+
+mob.pause(5000);
+
+const alertText = mob.getAlertText();
+
+log.info(alertText);
+
+const alertTextCorrect = alertText && typeof alertText === 'string' && alertText.length > 0 && alertText.includes('cool');
+assert.equal(alertTextCorrect, true);
+
+mob.alertAccept();
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getAppiumLogsFail.js b/e2e/tests/mob.ios/tests/mob.ios.getAppiumLogsFail.js
new file mode 100644
index 00000000..6f51f248
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getAppiumLogsFail.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+const logs = mob.getAppiumLogs();
+log.info(logs);
+const logsCorrect = logs && Array.isArray(logs);
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesFail.js b/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesFail.js
new file mode 100644
index 00000000..b312a973
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesFail.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+const capabilities = mob.getCapabilities();
+log.info(capabilities);
+
+const capsValid = !!capabilities && !!capabilities.aaa && !!capabilities.bbb;
+assert.equal(capsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesPass.js b/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesPass.js
new file mode 100644
index 00000000..1bdcfd19
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getCapabilitiesPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+const capabilities = mob.getCapabilities();
+log.info(capabilities);
+
+const capsValid = !!capabilities && !!capabilities.platformName;
+assert.equal(capsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getDeviceLogsFail.js b/e2e/tests/mob.ios/tests/mob.ios.getDeviceLogsFail.js
new file mode 100644
index 00000000..14a23acc
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getDeviceLogsFail.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+
+const logs = mob.getDeviceLogs();
+log.info(logs);
+const logsCorrect = logs && Array.isArray(logs);
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getDeviceTimePass.js b/e2e/tests/mob.ios/tests/mob.ios.getDeviceTimePass.js
new file mode 100644
index 00000000..2d79a62a
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getDeviceTimePass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+
+const time = mob.getDeviceTime();
+log.info(time);
+
+const timeCorrect = time && typeof time === 'string' && time.length > 0;
+assert.equal(timeCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getLocationPass.js b/e2e/tests/mob.ios/tests/mob.ios.getLocationPass.js
new file mode 100644
index 00000000..45f6545b
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getLocationPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+
+var el1 = mob.findElement('//XCUIElementTypeTextField[@name="IntegerA"]');
+
+const location = mob.getLocation(el1);
+log.info(location);
+
+const locationCorrect = !!location && !!location.x && !!location.y;
+assert.equal(locationCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.getSourcePass.js b/e2e/tests/mob.ios/tests/mob.ios.getSourcePass.js
new file mode 100644
index 00000000..920e865b
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.getSourcePass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+
+const source = mob.getSource();
+
+log.info(source);
+
+const sourceCorrect = source && typeof source === 'string' && source.length > 0;
+assert.equal(sourceCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.isAppInstalledPass.js b/e2e/tests/mob.ios/tests/mob.ios.isAppInstalledPass.js
new file mode 100644
index 00000000..bce14442
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.isAppInstalledPass.js
@@ -0,0 +1,20 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+const appId = 'io.appium.TestApp';
+
+const installed = mob.isAppInstalled(appId);
+log.info(installed);
+assert.equal(installed, true);
+
+mob.closeApp();
+
+mob.pause(2000);
+
+mob.launchApp();
+
+mob.resetApp();
+
+mob.removeApp(appId);
+
+mob.installApp(caps.app);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.isWebViewContextPass.js b/e2e/tests/mob.ios/tests/mob.ios.isWebViewContextPass.js
new file mode 100644
index 00000000..f75a08a9
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.isWebViewContextPass.js
@@ -0,0 +1,30 @@
+const caps3 = require('../assets/caps3');
+mob.init(caps3);
+
+const toWebViewPathClick = '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable/XCUIElementTypeCell[18]';
+const webViewPAth = '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeWebView';
+
+mob.click(toWebViewPathClick);
+
+mob.waitForExist(webViewPAth);
+mob.waitForVisible(webViewPAth);
+
+assert.pass();
+
+let isWebViewContext = mob.isWebViewContext();
+log.info('isWebViewContext 1');
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, false);
+
+mob.setNativeContext();
+
+isWebViewContext = mob.isWebViewContext();
+log.info('isWebViewContext 3');
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, false);
+
+mob.setContext('NATIVE_APP');
+isWebViewContext = mob.isWebViewContext();
+log.info('isWebViewContext 4');
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, false);
diff --git a/e2e/tests/mob.ios/tests/mob.ios.scrollIntoElementPass.js b/e2e/tests/mob.ios/tests/mob.ios.scrollIntoElementPass.js
new file mode 100644
index 00000000..ad6b46e4
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.scrollIntoElementPass.js
@@ -0,0 +1,30 @@
+const caps3 = require('../assets/caps3');
+
+mob.init(caps3);
+
+mob.scrollIntoElement(
+ '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable',
+ '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable/XCUIElementTypeCell[18]',
+ 0,
+ -10
+);
+
+mob.pause(15000);
+
+mob.swipe(
+ '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable/XCUIElementTypeCell[1]',
+ 0,
+ -300
+);
+
+mob.pause(15000);
+
+mob.swipeElement(
+ '//XCUIElementTypeApplication[@name="UIKitCatalog"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeTable/XCUIElementTypeCell[1]',
+ 0,
+ 600
+);
+
+mob.swipeScreen(0,0,0, -900);
+
+mob.pause(25000);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.takeScreenshotPass.js b/e2e/tests/mob.ios/tests/mob.ios.takeScreenshotPass.js
new file mode 100644
index 00000000..6565e69a
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.takeScreenshotPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+
+mob.setTimeout(5000);
+
+var screen = mob.takeScreenshot();
+const screenCorrect = screen && typeof screen === 'string' && screen.length > 0;
+assert.equal(screenCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.transactionPass.js b/e2e/tests/mob.ios/tests/mob.ios.transactionPass.js
new file mode 100644
index 00000000..b88b9c04
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.transactionPass.js
@@ -0,0 +1,4 @@
+const caps = require('../assets/caps');
+mob.transaction('transaction 1');
+mob.init(caps);
+mob.transaction('transaction 2');
\ No newline at end of file
diff --git a/e2e/tests/mob.ios/tests/mob.ios.waitForExistPass.js b/e2e/tests/mob.ios/tests/mob.ios.waitForExistPass.js
new file mode 100644
index 00000000..4c2970af
--- /dev/null
+++ b/e2e/tests/mob.ios/tests/mob.ios.waitForExistPass.js
@@ -0,0 +1,23 @@
+const caps = require('../assets/caps');
+
+mob.init(caps);
+const testGesture = '//XCUIElementTypeStaticText[@name="Test Gesture"]';
+const legal = '//XCUIElementTypeLink[@name="Legal"]';
+
+let exist = mob.isExist(legal);
+let visible = mob.isVisible(legal);
+
+assert.equal(exist, false);
+assert.equal(visible, false);
+
+const location = mob.getLocation(testGesture);
+mob.tap(location.x, location.y);
+mob.click(testGesture);
+
+mob.waitForExist(legal);
+mob.waitForVisible(legal);
+exist = mob.isExist(legal);
+visible = mob.isVisible(legal);
+
+assert.equal(exist, true);
+assert.equal(visible, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web.js b/e2e/tests/mob.web.js
new file mode 100644
index 00000000..60e7ef40
--- /dev/null
+++ b/e2e/tests/mob.web.js
@@ -0,0 +1,239 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+const before = mocha.before;
+const assert = require('chai').assert;
+
+const afterStart = config.afterStart;
+const testsFolder = '/mob.web/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('mob-web-module', () => {
+ before(() => {
+ if (process.platform === 'darwin') {
+ assert.equal(!!process.env.udid, true, 'Please set "udid" env');
+ assert.equal(!!process.env.deviceName, true, 'Please set "deviceName" env');
+ assert.equal(!!process.env.platformVersion, true, 'Please set "deviceName" platformVersion');
+ }
+ });
+
+ it('[getCapabilities] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getCapabilitiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCapabilities] not correct', async () => {
+ const response = await cliProcess.execute('mob.web.getCapabilitiesFail.js');
+ shouldFail(response);
+ });
+
+ it('[init] correct', async () => {
+ const response = await cliProcess.execute('mob.web.initPass.js');
+ shouldPass(response);
+ });
+
+ it('[dispose] correct', async () => {
+ const response = await cliProcess.execute('mob.web.disposePass.js');
+ shouldPass(response);
+ });
+
+ it('[transaction] correct', async () => {
+ const response = await cliProcess.execute('mob.web.transactionPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertAccept] correct', async () => {
+ const response = await cliProcess.execute('mob.web.alertAcceptPass.js');
+ shouldPass(response);
+ });
+
+ it('[alertDismiss] correct', async () => {
+ const response = await cliProcess.execute('mob.web.alertDismissPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertText] correct', async () => {
+ const response = await cliProcess.execute('mob.web.assertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertTitle] correct', async () => {
+ const response = await cliProcess.execute('mob.web.assertTitlePass.js');
+ shouldPass(response);
+ });
+
+ it('[assertValue] correct', async () => {
+ const response = await cliProcess.execute('mob.web.assertValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[back] correct', async () => {
+ const response = await cliProcess.execute('mob.web.backPass.js');
+ shouldPass(response);
+ });
+
+ it('[clear] correct', async () => {
+ const response = await cliProcess.execute('mob.web.clearPass.js');
+ shouldPass(response);
+ });
+
+ it('[click] correct', async () => {
+ const response = await cliProcess.execute('mob.web.clickPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickHidden] correct', async () => {
+ const response = await cliProcess.execute('mob.web.clickHiddenPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickLong] correct', async () => {
+ const response = await cliProcess.execute('mob.web.clickLongPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickMultipleTimes] correct', async () => {
+ const response = await cliProcess.execute('mob.web.clickMultipleTimesPass.js');
+ shouldPass(response);
+ });
+
+ it('[execute] correct', async () => {
+ const response = await cliProcess.execute('mob.web.executePass.js');
+ shouldPass(response);
+ });
+
+ it('[findElement] correct', async () => {
+ const response = await cliProcess.execute('mob.web.findElementPass.js');
+ shouldPass(response);
+ });
+
+ it('[findElements] correct', async () => {
+ const response = await cliProcess.execute('mob.web.findElementsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAlertText] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getAlertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAlertText] fail', async () => {
+ const response = await cliProcess.execute('mob.web.getAppiumLogsFail.js');
+ shouldFail(response);
+ });
+
+ it('[getDeviceLogs] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getDeviceLogsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getBrowserLogs] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getBrowserLogsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getLocation] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getLocationPass.js');
+ shouldPass(response);
+ });
+
+ it('[getSource] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[getText] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[getValue] correct', async () => {
+ const response = await cliProcess.execute('mob.web.getValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[hideKeyboard] correct', async () => {
+ const response = await cliProcess.execute('mob.web.hideKeyboardPass.js');
+ shouldPass(response);
+ });
+
+ it('[isExist] correct', async () => {
+ const response = await cliProcess.execute('mob.web.isExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[isVisible] correct', async () => {
+ const response = await cliProcess.execute('mob.web.isVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[isWebViewContext] correct', async () => {
+ const response = await cliProcess.execute('mob.web.isWebViewContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[open] correct', async () => {
+ const response = await cliProcess.execute('mob.web.openPass.js');
+ shouldPass(response);
+ });
+
+ it('[pause] correct', async () => {
+ const response = await cliProcess.execute('mob.web.pausePass.js');
+ shouldPass(response);
+ });
+
+ it('[selectFrame] correct', async () => {
+ const response = await cliProcess.execute('mob.web.selectFramePass.js');
+ shouldPass(response);
+ });
+
+ it('[sendKeys] correct', async () => {
+ const response = await cliProcess.execute('mob.web.sendKeysPass.js');
+ shouldPass(response);
+ });
+
+ it('[setContext] correct', async () => {
+ const response = await cliProcess.execute('mob.web.setContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[setNativeContext] correct', async () => {
+ const response = await cliProcess.execute('mob.web.setNativeContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[setNativeContext] correct', async () => {
+ const response = await cliProcess.execute('mob.web.setTimeoutPass.js');
+ shouldPass(response);
+ });
+
+ it('[setWebViewContext] correct', async () => {
+ const response = await cliProcess.execute('mob.web.setWebViewContextPass.js');
+ shouldPass(response);
+ });
+
+ it('[takeScreenshot] correct', async () => {
+ const response = await cliProcess.execute('mob.web.takeScreenshotPass.js');
+ shouldPass(response);
+ });
+
+ it('[type] correct', async () => {
+ const response = await cliProcess.execute('mob.web.typePass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForExist] correct', async () => {
+ const response = await cliProcess.execute('mob.web.waitForExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForVisible] correct', async () => {
+ const response = await cliProcess.execute('mob.web.waitForVisiblePass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/mob.web/assets/caps.js b/e2e/tests/mob.web/assets/caps.js
new file mode 100644
index 00000000..04bf967e
--- /dev/null
+++ b/e2e/tests/mob.web/assets/caps.js
@@ -0,0 +1,14 @@
+if (process.platform === 'darwin') {
+ module.exports = {
+ platformName: 'iOS',
+ browserName: 'Safari',
+ automationName: 'XCUITest',
+ deviceName: process.env.deviceName,
+ platformVersion: process.env.platformVersion,
+ udid: process.env.udid
+ };
+} else {
+ module.exports = {
+ platformName: 'Android'
+ };
+}
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.alertAcceptPass.js b/e2e/tests/mob.web/tests/mob.web.alertAcceptPass.js
new file mode 100644
index 00000000..74d1bccc
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.alertAcceptPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.click('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a');
+mob.alertAccept();
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.alertDismissPass.js b/e2e/tests/mob.web/tests/mob.web.alertDismissPass.js
new file mode 100644
index 00000000..ab4ef69b
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.alertDismissPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.click('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a');
+mob.alertDismiss();
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.assertTextPass.js b/e2e/tests/mob.web/tests/mob.web.assertTextPass.js
new file mode 100644
index 00000000..2fa8f999
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.assertTextPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const element = mob.findElement('#js-link-box-en > strong');
+const selectedText = mob.getText(element);
+if(selectedText){
+ mob.assertText('#js-link-box-en > strong', selectedText);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.assertTitlePass.js b/e2e/tests/mob.web/tests/mob.web.assertTitlePass.js
new file mode 100644
index 00000000..d4861836
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.assertTitlePass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const title = mob.getTitle();
+mob.assertTitle(title);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.assertValuePass.js b/e2e/tests/mob.web/tests/mob.web.assertValuePass.js
new file mode 100644
index 00000000..552ce8aa
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.assertValuePass.js
@@ -0,0 +1,19 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const element = mob.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+let selectedValue;
+
+for (var opt of opts) {
+ if (opt.isSelected()) {
+ selectedValue = opt.getValue();
+ }
+}
+
+if(selectedValue){
+ mob.assertValue("id=searchLanguage", selectedValue);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.backPass.js b/e2e/tests/mob.web/tests/mob.web.backPass.js
new file mode 100644
index 00000000..61f803a6
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.backPass.js
@@ -0,0 +1,14 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const element = mob.findElement("#js-link-box-en");
+element.click();
+
+let url = mob.getUrl();
+assert.equal("https://en.m.wikipedia.org/wiki/Main_Page", url);
+
+mob.back();
+
+url = mob.getUrl();
+assert.equal("https://www.wikipedia.org/", url);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.clearPass.js b/e2e/tests/mob.web/tests/mob.web.clearPass.js
new file mode 100644
index 00000000..a5368589
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.clearPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+mob.type("id=searchInput", "wiki");
+mob.clear("id=searchInput");
+const value = mob.getValue("id=searchInput");
+const equal = value === '';
+assert.equal(equal, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.clickHiddenPass.js b/e2e/tests/mob.web/tests/mob.web.clickHiddenPass.js
new file mode 100644
index 00000000..3c4bf9ac
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.clickHiddenPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+mob.clickHidden("#js-lang-lists > div:nth-child(2) > ul > li:nth-child(3) > a");
+const url = mob.getUrl();
+assert.equal("https://en.m.wikipedia.org/wiki/Main_Page", url);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.clickLongPass.js b/e2e/tests/mob.web/tests/mob.web.clickLongPass.js
new file mode 100644
index 00000000..a4378afb
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.clickLongPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.clickLong('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a', 1000);
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.clickMultipleTimesPass.js b/e2e/tests/mob.web/tests/mob.web.clickMultipleTimesPass.js
new file mode 100644
index 00000000..239b8844
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.clickMultipleTimesPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.clickMultipleTimes('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a', 4);
+mob.pause(2000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.clickPass.js b/e2e/tests/mob.web/tests/mob.web.clickPass.js
new file mode 100644
index 00000000..a5873fed
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.clickPass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.click('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.disposePass.js b/e2e/tests/mob.web/tests/mob.web.disposePass.js
new file mode 100644
index 00000000..ced4ab62
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.disposePass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+mob.dispose();
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.executePass.js b/e2e/tests/mob.web/tests/mob.web.executePass.js
new file mode 100644
index 00000000..24ba9afa
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.executePass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.execute(function(){alert('p');});
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.findElementPass.js b/e2e/tests/mob.web/tests/mob.web.findElementPass.js
new file mode 100644
index 00000000..2aa34a49
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.findElementPass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const element = mob.findElement('#js-link-box-en > strong');
+const selectedText = mob.getText(element);
+
+if(selectedText){
+ mob.assertText('#js-link-box-en > strong', selectedText);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.findElementsPass.js b/e2e/tests/mob.web/tests/mob.web.findElementsPass.js
new file mode 100644
index 00000000..9abd1ed0
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.findElementsPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const elements = mob.findElements("#www-wikipedia-org > div.central-featured > div.central-featured-lang");
+const elementsCorrect = elements && Array.isArray(elements) && elements.length > 0;
+assert.equal(elementsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getAlertTextPass.js b/e2e/tests/mob.web/tests/mob.web.getAlertTextPass.js
new file mode 100644
index 00000000..9f24f3f6
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getAlertTextPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://javascript.info/alert-prompt-confirm');
+mob.click('body > div.page-wrapper.page-wrapper_sidebar_on > div.page.page_sidebar_on.page_inner_padding.page_sidebar-animation-on > div.page__inner > main > div.content > div > div > div > div.task__content > p:nth-child(2) > a');
+const text = mob.getAlertText();
+assert.equal(text, 'What is your name?');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getAppiumLogsFail.js b/e2e/tests/mob.web/tests/mob.web.getAppiumLogsFail.js
new file mode 100644
index 00000000..f23141f2
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getAppiumLogsFail.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const logs = mob.getAppiumLogs();
+const logsCorrect = logs && Array.isArray(logs);
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getBrowserLogsPass.js b/e2e/tests/mob.web/tests/mob.web.getBrowserLogsPass.js
new file mode 100644
index 00000000..da663690
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getBrowserLogsPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+mob.open("https://en.wikipedia.org/wiki/Main_Page");
+const logs = mob.getBrowserLogs();
+log.info(logs.length);
+const logsCorrect = logs && Array.isArray(logs) && logs.length > 0;
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getCapabilitiesFail.js b/e2e/tests/mob.web/tests/mob.web.getCapabilitiesFail.js
new file mode 100644
index 00000000..8d95da6e
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getCapabilitiesFail.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+const capabilities = mob.getCapabilities();
+const capsValid = !!capabilities && !!capabilities.aaa && !!capabilities.bb;
+assert.equal(capsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getCapabilitiesPass.js b/e2e/tests/mob.web/tests/mob.web.getCapabilitiesPass.js
new file mode 100644
index 00000000..d7b16e20
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getCapabilitiesPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+const capabilities = mob.getCapabilities();
+const capsValid = !!capabilities && !!capabilities.platformName && !!capabilities.browserName;
+assert.equal(capsValid, true, 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getDeviceLogsPass.js b/e2e/tests/mob.web/tests/mob.web.getDeviceLogsPass.js
new file mode 100644
index 00000000..ec10a503
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getDeviceLogsPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const logs = mob.getDeviceLogs();
+
+const logsCorrect = logs && Array.isArray(logs) && logs.length > 0;
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getLocationPass.js b/e2e/tests/mob.web/tests/mob.web.getLocationPass.js
new file mode 100644
index 00000000..0b823a3e
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getLocationPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const loc = mob.getLocation("id=searchInput");
+log.info(loc);
+
+const locCorrect = !!loc && !!loc.x && !!loc.y;
+
+assert.equal(locCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getSourcePass.js b/e2e/tests/mob.web/tests/mob.web.getSourcePass.js
new file mode 100644
index 00000000..7bc5a8d7
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getSourcePass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://www.wikipedia.org/');
+const source = mob.getSource();
+const sourceCorrect = source && typeof source === 'string' && source.length > 0;
+assert.equal(sourceCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getTextPass.js b/e2e/tests/mob.web/tests/mob.web.getTextPass.js
new file mode 100644
index 00000000..404e5264
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getTextPass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("wikipedia.org");
+const text = mob.getText('#js-link-box-en > strong');
+log.info(text);
+const textCorrect = text && typeof text === 'string' && text.length > 0;
+assert.equal(textCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.getValuePass.js b/e2e/tests/mob.web/tests/mob.web.getValuePass.js
new file mode 100644
index 00000000..ebd86e5a
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.getValuePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.type("id=searchInput", "wiki");
+mob.pause(5000);
+mob.clear("id=searchInput");
+const value = mob.getValue("id=searchInput");
+const equal = value === '';
+assert.equal(equal, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.hideKeyboardPass.js b/e2e/tests/mob.web/tests/mob.web.hideKeyboardPass.js
new file mode 100644
index 00000000..ff37ac41
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.hideKeyboardPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.click("id=searchInput");
+mob.type("id=searchInput", "wiki");
+mob.pause(5000);
+mob.hideKeyboard("pressKey", "Search");
+mob.pause(5000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.initPass.js b/e2e/tests/mob.web/tests/mob.web.initPass.js
new file mode 100644
index 00000000..79296f01
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.initPass.js
@@ -0,0 +1,3 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.isExistPass.js b/e2e/tests/mob.web/tests/mob.web.isExistPass.js
new file mode 100644
index 00000000..b20d30e0
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.isExistPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const isExist = mob.isExist("id=searchLanguage");
+assert.equal(isExist, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.isVisiblePass.js b/e2e/tests/mob.web/tests/mob.web.isVisiblePass.js
new file mode 100644
index 00000000..34fbde9a
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.isVisiblePass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const isVisible = mob.isVisible("id=search-input");
+assert.equal(isVisible, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.isWebViewContextPass.js b/e2e/tests/mob.web/tests/mob.web.isWebViewContextPass.js
new file mode 100644
index 00000000..e0d8db3b
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.isWebViewContextPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const isWebViewContext = mob.isWebViewContext();
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.openPass.js b/e2e/tests/mob.web/tests/mob.web.openPass.js
new file mode 100644
index 00000000..e0d8db3b
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.openPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const isWebViewContext = mob.isWebViewContext();
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.pausePass.js b/e2e/tests/mob.web/tests/mob.web.pausePass.js
new file mode 100644
index 00000000..cac54a8c
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.pausePass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+const isWebViewContext = mob.isWebViewContext();
+log.info(isWebViewContext);
+assert.equal(isWebViewContext, true);
+mob.pause(5000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.scrollIntoViewPass.js b/e2e/tests/mob.web/tests/mob.web.scrollIntoViewPass.js
new file mode 100644
index 00000000..5447c741
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.scrollIntoViewPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org/");
+mob.pause(5000);
+mob.scrollIntoView('#www-wikipedia-org > p', true);
+mob.pause(5000);
+const isVisible = mob.isVisible('#www-wikipedia-org > p');
+assert.equal(isVisible, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.selectFramePass.js b/e2e/tests/mob.web/tests/mob.web.selectFramePass.js
new file mode 100644
index 00000000..2ad53269
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.selectFramePass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert');
+mob.selectFrame('id=iframeResult');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.sendKeysPass.js b/e2e/tests/mob.web/tests/mob.web.sendKeysPass.js
new file mode 100644
index 00000000..e2a13f8f
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.sendKeysPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.type("id=searchInput", "wiki");
+mob.sendKeys("Enter");
+
+const url = mob.getUrl();
+assert.notEqual("https://www.wikipedia.org/", url);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.setContextPass.js b/e2e/tests/mob.web/tests/mob.web.setContextPass.js
new file mode 100644
index 00000000..e0d17143
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.setContextPass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.setContext('NATIVE_APP');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.setNativeContextPass.js b/e2e/tests/mob.web/tests/mob.web.setNativeContextPass.js
new file mode 100644
index 00000000..47bf8c8a
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.setNativeContextPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.setNativeContext();
+mob.pause(6000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.setTimeoutPass.js b/e2e/tests/mob.web/tests/mob.web.setTimeoutPass.js
new file mode 100644
index 00000000..c6446fd3
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.setTimeoutPass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert');
+mob.setTimeout(60000);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.setWebViewContextPass.js b/e2e/tests/mob.web/tests/mob.web.setWebViewContextPass.js
new file mode 100644
index 00000000..6aec8876
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.setWebViewContextPass.js
@@ -0,0 +1,4 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.setWebViewContext();
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.takeScreenshotPass.js b/e2e/tests/mob.web/tests/mob.web.takeScreenshotPass.js
new file mode 100644
index 00000000..222c0b67
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.takeScreenshotPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+var ss = mob.takeScreenshot(); //Take a screenshot of the current page or screen and return it as base64 encoded string.
+const ssCorrect = ss && typeof ss === 'string' && ss.length > 0;
+assert.equal(ssCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.transactionPass.js b/e2e/tests/mob.web/tests/mob.web.transactionPass.js
new file mode 100644
index 00000000..a5c7e1cb
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.transactionPass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.transaction('transaction');
+mob.open('wikipedia.org');
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.typePass.js b/e2e/tests/mob.web/tests/mob.web.typePass.js
new file mode 100644
index 00000000..923843ae
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.typePass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open("https://www.wikipedia.org");
+mob.click("id=searchInput");
+mob.type("id=searchInput", "wiki");
+const value = mob.getValue("id=searchInput");
+const equal = value === 'wiki';
+assert.equal(equal, true);
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.waitForExistPass.js b/e2e/tests/mob.web/tests/mob.web.waitForExistPass.js
new file mode 100644
index 00000000..6b8cea73
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.waitForExistPass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('wikipedia.org');
+mob.waitForExist('#www-wikipedia-org > div.central-textlogo > h1 > strong')
\ No newline at end of file
diff --git a/e2e/tests/mob.web/tests/mob.web.waitForVisiblePass.js b/e2e/tests/mob.web/tests/mob.web.waitForVisiblePass.js
new file mode 100644
index 00000000..124d9bee
--- /dev/null
+++ b/e2e/tests/mob.web/tests/mob.web.waitForVisiblePass.js
@@ -0,0 +1,5 @@
+const caps = require('../assets/caps');
+mob.init(caps);
+mob.setTimeout(6000);
+mob.open('wikipedia.org');
+mob.waitForVisible('#www-wikipedia-org > div.central-textlogo > h1 > strong');
\ No newline at end of file
diff --git a/e2e/tests/pdf.js b/e2e/tests/pdf.js
new file mode 100644
index 00000000..480ee405
--- /dev/null
+++ b/e2e/tests/pdf.js
@@ -0,0 +1,54 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/pdf/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('pdf', () => {
+ it('assert correct page', async () => {
+ const response = await cliProcess.execute('1.js');
+ shouldPass(response);
+ });
+
+ it('assert incorect page fail', async () => {
+ const response = await cliProcess.execute('2.js');
+ shouldFail(response);
+ });
+
+ it('assert wrong pdf path fail', async () => {
+ const response = await cliProcess.execute('3.js');
+ shouldFail(response);
+ });
+
+ it('assertNot correct page', async () => {
+ const response = await cliProcess.execute('4.js');
+ shouldFail(response);
+ });
+
+ it('assertNot incorect page fail', async () => {
+ const response = await cliProcess.execute('5.js');
+ shouldPass(response);
+ });
+
+ it('assertNot wrong pdf path fail', async () => {
+ const response = await cliProcess.execute('6.js');
+ shouldFail(response);
+ });
+
+ it('count valid', async () => {
+ const response = await cliProcess.execute('7.js');
+ shouldPass(response);
+ });
+
+ it('count not valid', async () => {
+ const response = await cliProcess.execute('8.js');
+ shouldFail(response);
+ });
+});
diff --git a/e2e/tests/pdf/assets/test.pdf b/e2e/tests/pdf/assets/test.pdf
new file mode 100644
index 00000000..e9c8b47c
Binary files /dev/null and b/e2e/tests/pdf/assets/test.pdf differ
diff --git a/e2e/tests/pdf/tests/1.js b/e2e/tests/pdf/tests/1.js
new file mode 100644
index 00000000..119e759c
--- /dev/null
+++ b/e2e/tests/pdf/tests/1.js
@@ -0,0 +1,4 @@
+const path = require('path');
+const pdfPath = path.resolve(__dirname, '../assets/test.pdf');
+
+pdf.assert(pdfPath, 'Dictumst quisque sagittis purus sit', 1, "Text not found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/2.js b/e2e/tests/pdf/tests/2.js
new file mode 100644
index 00000000..3df36d68
--- /dev/null
+++ b/e2e/tests/pdf/tests/2.js
@@ -0,0 +1 @@
+pdf.assert('../assets/test.pdf', 'Dictumst quisque sagittis purus sit', 2, "Text not found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/3.js b/e2e/tests/pdf/tests/3.js
new file mode 100644
index 00000000..02c8df49
--- /dev/null
+++ b/e2e/tests/pdf/tests/3.js
@@ -0,0 +1 @@
+pdf.assert('../assets/testtesttesttest.pdf', 'Dictumst quisque sagittis purus sit', 13, "Text not found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/4.js b/e2e/tests/pdf/tests/4.js
new file mode 100644
index 00000000..393c70f2
--- /dev/null
+++ b/e2e/tests/pdf/tests/4.js
@@ -0,0 +1 @@
+pdf.assertNot('../assets/test.pdf', 'Dictumst quisque sagittis purus sit', 1, "Text found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/5.js b/e2e/tests/pdf/tests/5.js
new file mode 100644
index 00000000..a493fa54
--- /dev/null
+++ b/e2e/tests/pdf/tests/5.js
@@ -0,0 +1 @@
+pdf.assertNot('../assets/test.pdf', 'Dictumst quisque sagittis purus sit', 2, "Text found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/6.js b/e2e/tests/pdf/tests/6.js
new file mode 100644
index 00000000..52f14544
--- /dev/null
+++ b/e2e/tests/pdf/tests/6.js
@@ -0,0 +1 @@
+pdf.assertNot('../assets/testtesttesttest.pdf', 'Dictumst quisque sagittis purus sit', 1, "Text found in PDF");
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/7.js b/e2e/tests/pdf/tests/7.js
new file mode 100644
index 00000000..a45fb830
--- /dev/null
+++ b/e2e/tests/pdf/tests/7.js
@@ -0,0 +1,2 @@
+const count = pdf.count('../assets/test.pdf', 'Dictumst quisque sagittis purus sit', 1);
+assert.equal(count, 1 , 'Count not valid');
\ No newline at end of file
diff --git a/e2e/tests/pdf/tests/8.js b/e2e/tests/pdf/tests/8.js
new file mode 100644
index 00000000..c302fadf
--- /dev/null
+++ b/e2e/tests/pdf/tests/8.js
@@ -0,0 +1,2 @@
+const count = pdf.count('../assets/test.pdf', 'Dictumst quisque sagittis purus sit', 2);
+assert.equal(count, 1 , 'Count not valid');
\ No newline at end of file
diff --git a/e2e/tests/serial.js b/e2e/tests/serial.js
new file mode 100644
index 00000000..2e700c29
--- /dev/null
+++ b/e2e/tests/serial.js
@@ -0,0 +1,31 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/serial/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('serial', () => {
+ it('list correct', async () => {
+ const response = await cliProcess.execute('list.js');
+ shouldPass(response);
+ });
+ it('open correct', async () => {
+ const response = await cliProcess.execute('open.js');
+ shouldPass(response);
+ });
+ it('waitForText correct', async () => {
+ const response = await cliProcess.execute('waitForText.js');
+ shouldPass(response);
+ });
+ it('write correct', async () => {
+ const response = await cliProcess.execute('write.js');
+ shouldPass(response);
+ });
+});
diff --git a/e2e/tests/serial/tests/list.js b/e2e/tests/serial/tests/list.js
new file mode 100644
index 00000000..e94590f9
--- /dev/null
+++ b/e2e/tests/serial/tests/list.js
@@ -0,0 +1,2 @@
+const list = serial.list();
+log.info(list);
\ No newline at end of file
diff --git a/e2e/tests/serial/tests/open.js b/e2e/tests/serial/tests/open.js
new file mode 100644
index 00000000..1e02045b
--- /dev/null
+++ b/e2e/tests/serial/tests/open.js
@@ -0,0 +1 @@
+serial.open();
\ No newline at end of file
diff --git a/e2e/tests/serial/tests/waitForText.js b/e2e/tests/serial/tests/waitForText.js
new file mode 100644
index 00000000..3616c9b9
--- /dev/null
+++ b/e2e/tests/serial/tests/waitForText.js
@@ -0,0 +1 @@
+serial.waitForText();
\ No newline at end of file
diff --git a/e2e/tests/serial/tests/write.js b/e2e/tests/serial/tests/write.js
new file mode 100644
index 00000000..a4855ca4
--- /dev/null
+++ b/e2e/tests/serial/tests/write.js
@@ -0,0 +1 @@
+serial.write();
\ No newline at end of file
diff --git a/e2e/tests/shell.js b/e2e/tests/shell.js
new file mode 100644
index 00000000..4ce2dc83
--- /dev/null
+++ b/e2e/tests/shell.js
@@ -0,0 +1,19 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/shell/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('shell', () => {
+ it('exec correct', async () => {
+ const response = await cliProcess.execute('exec.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/shell/tests/exec.js b/e2e/tests/shell/tests/exec.js
new file mode 100644
index 00000000..f1a08628
--- /dev/null
+++ b/e2e/tests/shell/tests/exec.js
@@ -0,0 +1 @@
+shell.exec('node', ['--version']);
\ No newline at end of file
diff --git a/e2e/tests/soap.js b/e2e/tests/soap.js
new file mode 100644
index 00000000..533e3883
--- /dev/null
+++ b/e2e/tests/soap.js
@@ -0,0 +1,24 @@
+const cmd = require('../tools/cmd');
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/soap/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('soap', () => {
+ it('[describe] correct', async () => {
+ const response = await cliProcess.execute('soap.describePass.js');
+ shouldPass(response);
+ });
+
+ it('[get] correct', async () => {
+ const response = await cliProcess.execute('soap.getPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/soap/tests/soap.describePass.js b/e2e/tests/soap/tests/soap.describePass.js
new file mode 100644
index 00000000..1a6314bf
--- /dev/null
+++ b/e2e/tests/soap/tests/soap.describePass.js
@@ -0,0 +1,12 @@
+var txt = soap.describe('http://webservices.daehosting.com/services/isbnservice.wso?WSDL');
+log.info(txt);
+
+const xtxCorrect =
+ txt &&
+ typeof txt === 'string' &&
+ txt.length > 0 &&
+ txt.includes('ISBNService') &&
+ txt.includes('ISBNServiceSoap12') &&
+ txt.includes('IsValidISBN10');
+
+assert.equal(xtxCorrect, true);
diff --git a/e2e/tests/soap/tests/soap.getPass.js b/e2e/tests/soap/tests/soap.getPass.js
new file mode 100644
index 00000000..7b1cb5fc
--- /dev/null
+++ b/e2e/tests/soap/tests/soap.getPass.js
@@ -0,0 +1,7 @@
+var ret = soap.get('http://webservices.daehosting.com/services/isbnservice.wso?WSDL', 'IsValidISBN13', { sISBN: '9789059650886'});
+
+log.info(ret);
+
+const retCorrect = ret && ret.IsValidISBN13Result ;
+
+assert.equal(retCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/twilio.js b/e2e/tests/twilio.js
new file mode 100644
index 00000000..ddae26f4
--- /dev/null
+++ b/e2e/tests/twilio.js
@@ -0,0 +1,26 @@
+const cmd = require('../tools/cmd');
+const assert = require('chai').assert;
+const { shouldPass } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+const before = mocha.before;
+
+const afterStart = config.afterStart;
+const testsFolder = '/twilio/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('twilio', () => {
+ before(() => {
+ assert.equal(!!process.env.accountSid, true, 'Please set "accountSid" env');
+ assert.equal(!!process.env.authToken, true, 'Please set "authToken" env');
+ });
+
+ it('[init] correct', async () => {
+ const response = await cliProcess.execute('twilio.initPass.js');
+ shouldPass(response);
+ });
+});
\ No newline at end of file
diff --git a/e2e/tests/twilio/tests/twilio.getLastSmsPass.js b/e2e/tests/twilio/tests/twilio.getLastSmsPass.js
new file mode 100644
index 00000000..e8ea35ef
--- /dev/null
+++ b/e2e/tests/twilio/tests/twilio.getLastSmsPass.js
@@ -0,0 +1,4 @@
+twilio.init(process.env.accountSid, process.env.authToken);
+twilio.sendSms(process.env.accountSid, process.env.authToken, 'Hello');
+var msg = twilio.getLastSms(true, 8000, 400*60*1000);
+console.log("msg: " + msg);
\ No newline at end of file
diff --git a/e2e/tests/twilio/tests/twilio.initPass.js b/e2e/tests/twilio/tests/twilio.initPass.js
new file mode 100644
index 00000000..fe5d4b37
--- /dev/null
+++ b/e2e/tests/twilio/tests/twilio.initPass.js
@@ -0,0 +1 @@
+twilio.init(process.env.accountSid, process.env.authToken);
\ No newline at end of file
diff --git a/e2e/tests/twilio/tests/twilio.sendSmsPass.js b/e2e/tests/twilio/tests/twilio.sendSmsPass.js
new file mode 100644
index 00000000..e8ea35ef
--- /dev/null
+++ b/e2e/tests/twilio/tests/twilio.sendSmsPass.js
@@ -0,0 +1,4 @@
+twilio.init(process.env.accountSid, process.env.authToken);
+twilio.sendSms(process.env.accountSid, process.env.authToken, 'Hello');
+var msg = twilio.getLastSms(true, 8000, 400*60*1000);
+console.log("msg: " + msg);
\ No newline at end of file
diff --git a/e2e/tests/web.js b/e2e/tests/web.js
new file mode 100644
index 00000000..001c160d
--- /dev/null
+++ b/e2e/tests/web.js
@@ -0,0 +1,509 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/web/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('web-module-single', () => {
+ it('[dispose] correct', async () => {
+ const response = await cliProcess.execute('disposePass.js');
+ shouldPass(response);
+ });
+
+ it('[init] correct', async () => {
+ const response = await cliProcess.execute('initPass.js');
+ shouldPass(response);
+ });
+
+ it('[open] correct', async () => {
+ const response = await cliProcess.execute('openPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCapabilities] fail', async () => {
+ const response = await cliProcess.execute('getCapabilitiesFail.js');
+ shouldFail(response);
+ });
+
+ it('[getCapabilities] correct', async () => {
+ const response = await cliProcess.execute('getCapabilitiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[transaction] correct', async () => {
+ const response = await cliProcess.execute('transaction.js');
+ shouldPass(response);
+ });
+
+ it('[alertAccept] correct', async () => {
+ const response = await cliProcess.execute('alertAccept.js');
+ shouldPass(response);
+ });
+
+ it('[alertDismiss] correct', async () => {
+ const response = await cliProcess.execute('alertDismiss.js');
+ shouldPass(response);
+ });
+
+ it('[assertAlert] correct', async () => {
+ const response = await cliProcess.execute('assertAlertPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertAlert] not correct', async () => {
+ const response = await cliProcess.execute('assertAlertFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertExist] correct', async () => {
+ const response = await cliProcess.execute('assertExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertExist] not correct', async () => {
+ const response = await cliProcess.execute('assertExistFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertExist] correct with [findElement] and [isSelected]', async () => {
+ const response = await cliProcess.execute('assertSelectedLabelPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertSelectedLabel] not correct', async () => {
+ const response = await cliProcess.execute('assertSelectedLabelFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertSelectedValue] correct with [findElement] and [isSelected]', async () => {
+ const response = await cliProcess.execute('assertSelectedValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[assertSelectedValue] not correct', async () => {
+ const response = await cliProcess.execute('assertSelectedValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertText] correct', async () => {
+ const response = await cliProcess.execute('assertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertText] not correct', async () => {
+ const response = await cliProcess.execute('assertTextFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertTextNotPresent] correct', async () => {
+ const response = await cliProcess.execute('assertTextNotPresentPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertTextNotPresent] not correct', async () => {
+ const response = await cliProcess.execute('assertTextNotPresentFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertTextPresent] correct', async () => {
+ const response = await cliProcess.execute('assertTextPresentPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertTextPresent] not correct', async () => {
+ const response = await cliProcess.execute('assertTextPresentFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertTitle] correct with [getTitle]', async () => {
+ const response = await cliProcess.execute('assertTitlePass.js');
+ shouldPass(response);
+ });
+
+ it('[assertTitle] not correct', async () => {
+ const response = await cliProcess.execute('assertTitleFail.js');
+ shouldFail(response);
+ });
+
+ it('[assertValue] correct with [getValue] and [findElement] and [isSelected]', async () => {
+ const response = await cliProcess.execute('assertValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[assertValue] not correct', async () => {
+ const response = await cliProcess.execute('assertValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[back] correct with [getUrl] and [click] and [findElement]', async () => {
+ const response = await cliProcess.execute('backPass.js');
+ shouldPass(response);
+ });
+
+ it('[back] correct', async () => {
+ const response = await cliProcess.execute('backPass2.js');
+ shouldPass(response);
+ });
+
+ it('[clearValue] correct', async () => {
+ const response = await cliProcess.execute('clearValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[clearValue] not correct', async () => {
+ const response = await cliProcess.execute('clearValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[click] not correct', async () => {
+ const response = await cliProcess.execute('clickFail.js');
+ shouldFail(response);
+ });
+
+ it('[clickHidden] correct', async () => {
+ const response = await cliProcess.execute('clickHiddenPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickHidden] not correct', async () => {
+ const response = await cliProcess.execute('clickHiddenFail.js');
+ shouldFail(response);
+ });
+
+ it('[closeWindow] correct', async () => {
+ const response = await cliProcess.execute('closeWindowPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCookies] and [deleteCookies] correct', async () => {
+ const response = await cliProcess.execute('getCookiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[deleteCookies] not correct', async () => {
+ const response = await cliProcess.execute('deleteCookiesFail.js');
+ shouldFail(response);
+ });
+
+ it('[type] not correct', async () => {
+ const response = await cliProcess.execute('typeFail.js');
+ shouldFail(response);
+ });
+
+ it('[doubleClick] correct', async () => {
+ const response = await cliProcess.execute('doubleClickPass.js');
+ shouldPass(response);
+ });
+
+ it('[doubleClick] not correct', async () => {
+ const response = await cliProcess.execute('doubleClickFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForWindow] correct with [selectFrame]', async () => {
+ const response = await cliProcess.execute('waitForWindowPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForWindow] not correct with [selectFrame]', async () => {
+ const response = await cliProcess.execute('waitForWindowFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForVisible] correct', async () => {
+ const response = await cliProcess.execute('waitForVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForVisible] not correct', async () => {
+ const response = await cliProcess.execute('waitForVisibleFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForValue] correct', async () => {
+ const response = await cliProcess.execute('waitForValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForValue] not correct', async () => {
+ const response = await cliProcess.execute('waitForValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForText] correct', async () => {
+ const response = await cliProcess.execute('waitForTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForText] not correct', async () => {
+ const response = await cliProcess.execute('waitForTextFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForExist] correct', async () => {
+ const response = await cliProcess.execute('waitForExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForExist] not correct', async () => {
+ const response = await cliProcess.execute('waitForExistFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForNotExist] correct', async () => {
+ const response = await cliProcess.execute('waitForNotExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForNotExist] not correct', async () => {
+ const response = await cliProcess.execute('waitForNotExistFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForNotText] correct', async () => {
+ const response = await cliProcess.execute('waitForNotTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForNotText] not correct', async () => {
+ const response = await cliProcess.execute('waitForNotTextFail.js');
+ shouldFail(response);
+ });
+
+ it('[waitForNotValue] correct', async () => {
+ const response = await cliProcess.execute('waitForNotValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForNotValue] not correct', async () => {
+ const response = await cliProcess.execute('waitForNotValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[takeScreenshot] correct', async () => {
+ const response = await cliProcess.execute('takeScreenshotPass.js');
+ shouldPass(response);
+ });
+
+ it('[setWindowSize] and [getWindowSize] correct', async () => {
+ const response = await cliProcess.execute('setGetWindowSizePass.js');
+ shouldPass(response);
+ });
+
+ it('[setWindowSize] not correct', async () => {
+ const response = await cliProcess.execute('setWindowSizeFail.js');
+ shouldFail(response);
+ });
+
+ it('[setTimeout] correct', async () => {
+ const response = await cliProcess.execute('setTimeoutPass.js');
+ shouldPass(response);
+ });
+
+ it('[setTimeout] not correct', async () => {
+ const response = await cliProcess.execute('setTimeoutFail.js');
+ shouldFail(response);
+ });
+
+ it('[sendKeys] correct', async () => {
+ const response = await cliProcess.execute('sendKeysPass.js');
+ shouldPass(response);
+ });
+
+ it('[selectWindow] correct', async () => {
+ const response = await cliProcess.execute('selectWindowPass.js');
+ shouldPass(response);
+ });
+
+ it('[selectWindow] not correct', async () => {
+ const response = await cliProcess.execute('selectWindowFail.js');
+ shouldFail(response);
+ });
+
+ it('[select] correct', async () => {
+ const response = await cliProcess.execute('selectPass.js');
+ shouldPass(response);
+ });
+
+ it('[select] not correct', async () => {
+ const response = await cliProcess.execute('selectFail.js');
+ shouldFail(response);
+ });
+
+ it('[scrollToElement] correct', async () => {
+ const response = await cliProcess.execute('scrollToElementPass.js');
+ shouldPass(response);
+ });
+
+ it('[scrollToElement] not correct', async () => {
+ const response = await cliProcess.execute('scrollToElementFail.js');
+ shouldFail(response);
+ });
+
+ it('[rightClick] correct', async () => {
+ const response = await cliProcess.execute('rightClickPass.js');
+ shouldPass(response);
+ });
+
+ it('[rightClick] not correct', async () => {
+ const response = await cliProcess.execute('rightClickFail.js');
+ shouldFail(response);
+ });
+
+ it('[refresh] correct', async () => {
+ const response = await cliProcess.execute('refreshPass.js');
+ shouldPass(response);
+ });
+
+ it('[point] correct', async () => {
+ const response = await cliProcess.execute('pointPass.js');
+ shouldPass(response);
+ });
+
+ it('[point] not correct', async () => {
+ const response = await cliProcess.execute('pointFail.js');
+ shouldFail(response);
+ });
+
+ it('[isVisible] correct', async () => {
+ const response = await cliProcess.execute('isVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[isVisible] not correct', async () => {
+ const response = await cliProcess.execute('isVisibleFail.js');
+ shouldFail(response);
+ });
+
+ it('[makeVisible] correct', async () => {
+ const response = await cliProcess.execute('makeVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[makeVisible] not correct', async () => {
+ const response = await cliProcess.execute('makeVisibleFail.js');
+ shouldFail(response);
+ });
+
+ it('[isExist] correct', async () => {
+ const response = await cliProcess.execute('isExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[isExist] not correct', async () => {
+ const response = await cliProcess.execute('isExistFail.js');
+ shouldFail(response);
+ });
+
+ it('[isAlertPresent] correct', async () => {
+ const response = await cliProcess.execute('isAlertPresentPass.js');
+ shouldPass(response);
+ });
+
+ it('[isAlertPresent] not correct', async () => {
+ const response = await cliProcess.execute('isAlertPresentFail.js');
+ shouldFail(response);
+ });
+
+ it('[getAlertText] correct', async () => {
+ const response = await cliProcess.execute('getAlertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAlertText] not correct', async () => {
+ const response = await cliProcess.execute('getAlertTextFail.js');
+ shouldFail(response);
+ });
+
+ it('[getXMLPageSource] correct', async () => {
+ const response = await cliProcess.execute('getXMLPageSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[getXMLPageSource] not correct', async () => {
+ const response = await cliProcess.execute('getXMLPageSourceFail.js');
+ shouldFail(response);
+ });
+
+ it('[getWindowHandles] correct', async () => {
+ const response = await cliProcess.execute('getWindowHandlesPass.js');
+ shouldPass(response);
+ });
+
+ it('[getPageSource] correct', async () => {
+ const response = await cliProcess.execute('getPageSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[getElementCount] correct', async () => {
+ const response = await cliProcess.execute('getElementCountPass.js');
+ shouldPass(response);
+ });
+
+ it('[getCssValue] correct', async () => {
+ const response = await cliProcess.execute('getCssValuePass.js');
+ shouldPass(response);
+ });
+
+ it('[getCssValue] not correct', async () => {
+ const response = await cliProcess.execute('getCssValueFail.js');
+ shouldFail(response);
+ });
+
+ it('[getBrowserLogs] correct', async () => {
+ const response = await cliProcess.execute('getBrowserLogsPass.js');
+ shouldPass(response);
+ });
+
+ it('[getAttribute] correct', async () => {
+ const response = await cliProcess.execute('getAttributePass.js');
+ shouldPass(response);
+ });
+
+ it('[getAttribute] not correct', async () => {
+ const response = await cliProcess.execute('getAttributeFail.js');
+ shouldFail(response);
+ });
+
+ it('[findElements] correct', async () => {
+ const response = await cliProcess.execute('findElementsPass.js');
+ shouldPass(response);
+ });
+
+ it('[findElements] not correct', async () => {
+ const response = await cliProcess.execute('findElementsFail.js');
+ shouldFail(response);
+ });
+
+ it('[deselect] correct', async () => {
+ const response = await cliProcess.execute('deselectPass.js');
+ shouldPass(response);
+ });
+
+ it('[deselect] not correct', async () => {
+ const response = await cliProcess.execute('deselectFail.js');
+ shouldFail(response);
+ });
+
+ it('[dragAndDrop] correct', async () => {
+ const response = await cliProcess.execute('dragAndDropPass.js');
+ shouldPass(response);
+ });
+
+ it('[dragAndDrop] not correct', async () => {
+ const response = await cliProcess.execute('dragAndDropFail.js');
+ shouldFail(response);
+ });
+});
+
+// it('[fileBrowse] correct', async () => {
+// const response = await cliProcess.execute('fileBrowsePass.js');
+// shouldPass(response);
+// });
diff --git a/e2e/tests/web/assets/caps.js b/e2e/tests/web/assets/caps.js
new file mode 100644
index 00000000..60dbf6b4
--- /dev/null
+++ b/e2e/tests/web/assets/caps.js
@@ -0,0 +1,3 @@
+module.exports = {
+ h1Strong : '#www-wikipedia-org > div.central-textlogo > h1 > strong'
+};
diff --git a/e2e/tests/web/assets/image.jpg b/e2e/tests/web/assets/image.jpg
new file mode 100644
index 00000000..d070c5e9
Binary files /dev/null and b/e2e/tests/web/assets/image.jpg differ
diff --git a/e2e/tests/web/assets/image.zip b/e2e/tests/web/assets/image.zip
new file mode 100644
index 00000000..d0ea49cf
Binary files /dev/null and b/e2e/tests/web/assets/image.zip differ
diff --git a/e2e/tests/web/tests/alertAccept.js b/e2e/tests/web/tests/alertAccept.js
new file mode 100644
index 00000000..3d1ad83b
--- /dev/null
+++ b/e2e/tests/web/tests/alertAccept.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+web.alertAccept();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/alertDismiss.js b/e2e/tests/web/tests/alertDismiss.js
new file mode 100644
index 00000000..f055b8f8
--- /dev/null
+++ b/e2e/tests/web/tests/alertDismiss.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+web.alertDismiss();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertAlertFail.js b/e2e/tests/web/tests/assertAlertFail.js
new file mode 100644
index 00000000..f0b83193
--- /dev/null
+++ b/e2e/tests/web/tests/assertAlertFail.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+web.assertAlert('3');
+web.pause(3*1000)
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertAlertPass.js b/e2e/tests/web/tests/assertAlertPass.js
new file mode 100644
index 00000000..963474fd
--- /dev/null
+++ b/e2e/tests/web/tests/assertAlertPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+web.assertAlert('p');
+web.pause(3*1000)
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertExistFail.js b/e2e/tests/web/tests/assertExistFail.js
new file mode 100644
index 00000000..cd7038e3
--- /dev/null
+++ b/e2e/tests/web/tests/assertExistFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertExist("id=www-wikipedia-orgwww-wikipedia-org");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertExistPass.js b/e2e/tests/web/tests/assertExistPass.js
new file mode 100644
index 00000000..5eac89e9
--- /dev/null
+++ b/e2e/tests/web/tests/assertExistPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertExist("id=www-wikipedia-org");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertSelectedLabelFail.js b/e2e/tests/web/tests/assertSelectedLabelFail.js
new file mode 100644
index 00000000..23873094
--- /dev/null
+++ b/e2e/tests/web/tests/assertSelectedLabelFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertSelectedLabel("id=searchLanguage", "Not valid text", 600, false);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertSelectedLabelPass.js b/e2e/tests/web/tests/assertSelectedLabelPass.js
new file mode 100644
index 00000000..e0de1563
--- /dev/null
+++ b/e2e/tests/web/tests/assertSelectedLabelPass.js
@@ -0,0 +1,18 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+let selectedText;
+
+for (var opt of opts) {
+ if (opt.isSelected()) {
+ selectedText = web.getText(opt);
+ }
+}
+
+if(selectedText){
+ web.assertSelectedLabel("id=searchLanguage", selectedText, 600, false);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertSelectedValueFail.js b/e2e/tests/web/tests/assertSelectedValueFail.js
new file mode 100644
index 00000000..0c4eee8b
--- /dev/null
+++ b/e2e/tests/web/tests/assertSelectedValueFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertSelectedValue("id=searchLanguage", "Not valid text", 600, false);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertSelectedValuePass.js b/e2e/tests/web/tests/assertSelectedValuePass.js
new file mode 100644
index 00000000..9cb152ff
--- /dev/null
+++ b/e2e/tests/web/tests/assertSelectedValuePass.js
@@ -0,0 +1,18 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+let selectedValue;
+
+for (var opt of opts) {
+ if (opt.isSelected()) {
+ selectedValue = opt.getValue();
+ }
+}
+
+if(selectedValue){
+ web.assertSelectedValue("id=searchLanguage", selectedValue, 600, false);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTextFail.js b/e2e/tests/web/tests/assertTextFail.js
new file mode 100644
index 00000000..acf13ddf
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertText("#js-link-box-en > strong", "Not valid text", 600, false);
diff --git a/e2e/tests/web/tests/assertTextNotPresentFail.js b/e2e/tests/web/tests/assertTextNotPresentFail.js
new file mode 100644
index 00000000..4626024e
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextNotPresentFail.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const selector = '#www-wikipedia-org > div.central-textlogo > h1 > span';
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+
+web.waitForVisible(selector);
+
+const element = web.findElement(selector);
+const text = web.getText(element);
+web.assertTextNotPresent(text);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTextNotPresentPass.js b/e2e/tests/web/tests/assertTextNotPresentPass.js
new file mode 100644
index 00000000..2b8864a7
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextNotPresentPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertTextNotPresent("Not valid text", 600);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTextPass.js b/e2e/tests/web/tests/assertTextPass.js
new file mode 100644
index 00000000..cdbac137
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextPass.js
@@ -0,0 +1,16 @@
+const selector = '#www-wikipedia-org > div.central-textlogo > h1 > span';
+
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+
+web.waitForVisible(selector);
+
+const element = web.findElement(selector);
+const selectedText = web.getText(selector);
+
+if(selectedText){
+ web.assertText(selector, selectedText, 600, false);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTextPresentFail.js b/e2e/tests/web/tests/assertTextPresentFail.js
new file mode 100644
index 00000000..2be1efd1
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextPresentFail.js
@@ -0,0 +1,6 @@
+const selector = '#www-wikipedia-org > div.central-textlogo > h1 > span';
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.waitForVisible(selector);
+web.assertTextPresent("Not valid text", 600);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTextPresentPass.js b/e2e/tests/web/tests/assertTextPresentPass.js
new file mode 100644
index 00000000..bb8f1e97
--- /dev/null
+++ b/e2e/tests/web/tests/assertTextPresentPass.js
@@ -0,0 +1,11 @@
+const selector = '#www-wikipedia-org > div.central-textlogo > h1 > span';
+
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+
+web.waitForVisible(selector);
+
+const element = web.findElement(selector);
+const text = web.getText(element);
+web.assertTextPresent(text, 600);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTitleFail.js b/e2e/tests/web/tests/assertTitleFail.js
new file mode 100644
index 00000000..a348fff0
--- /dev/null
+++ b/e2e/tests/web/tests/assertTitleFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertTitle("Not valid text");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertTitlePass.js b/e2e/tests/web/tests/assertTitlePass.js
new file mode 100644
index 00000000..4e65ec0e
--- /dev/null
+++ b/e2e/tests/web/tests/assertTitlePass.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const title = web.getTitle();
+web.assertTitle(title);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertValueFail.js b/e2e/tests/web/tests/assertValueFail.js
new file mode 100644
index 00000000..e7ed2fe6
--- /dev/null
+++ b/e2e/tests/web/tests/assertValueFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.assertValue("id=searchLanguage", "Not valid value");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/assertValuePass.js b/e2e/tests/web/tests/assertValuePass.js
new file mode 100644
index 00000000..60dcca02
--- /dev/null
+++ b/e2e/tests/web/tests/assertValuePass.js
@@ -0,0 +1,18 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+let selectedValue;
+
+for (var opt of opts) {
+ if (opt.isSelected()) {
+ selectedValue = opt.getValue();
+ }
+}
+
+if(selectedValue){
+ web.assertValue("id=searchLanguage", selectedValue);
+} else {
+ assert.equal(1,2, 'Script broken');
+}
\ No newline at end of file
diff --git a/e2e/tests/web/tests/backPass.js b/e2e/tests/web/tests/backPass.js
new file mode 100644
index 00000000..40eed099
--- /dev/null
+++ b/e2e/tests/web/tests/backPass.js
@@ -0,0 +1,14 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const element = web.findElement("#js-link-box-en");
+element.click();
+
+let url = web.getUrl();
+assert.equal("https://en.wikipedia.org/wiki/Main_Page", url);
+
+web.back();
+
+url = web.getUrl();
+assert.equal("https://www.wikipedia.org/", url);
+
diff --git a/e2e/tests/web/tests/backPass2.js b/e2e/tests/web/tests/backPass2.js
new file mode 100644
index 00000000..5ae483da
--- /dev/null
+++ b/e2e/tests/web/tests/backPass2.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.back();
+
+let url = web.getUrl();
+
+assert.equal("data:,", url);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/clearValueFail.js b/e2e/tests/web/tests/clearValueFail.js
new file mode 100644
index 00000000..9dd8e155
--- /dev/null
+++ b/e2e/tests/web/tests/clearValueFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.clear("id=NOT_VALID");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/clearValuePass.js b/e2e/tests/web/tests/clearValuePass.js
new file mode 100644
index 00000000..e4c8ab6f
--- /dev/null
+++ b/e2e/tests/web/tests/clearValuePass.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+web.clear("id=searchInput");
+const value = web.getValue("id=searchInput");
+const equal = value === '';
+assert.equal(equal, true);
diff --git a/e2e/tests/web/tests/clickFail.js b/e2e/tests/web/tests/clickFail.js
new file mode 100644
index 00000000..ee54e7ae
--- /dev/null
+++ b/e2e/tests/web/tests/clickFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.click("id=NOT_VALID");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/clickHiddenFail.js b/e2e/tests/web/tests/clickHiddenFail.js
new file mode 100644
index 00000000..76ed6786
--- /dev/null
+++ b/e2e/tests/web/tests/clickHiddenFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");;
+web.clickHidden("#not-valid");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/clickHiddenPass.js b/e2e/tests/web/tests/clickHiddenPass.js
new file mode 100644
index 00000000..d25ee86b
--- /dev/null
+++ b/e2e/tests/web/tests/clickHiddenPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.clickHidden("#js-lang-lists > div:nth-child(2) > ul > li:nth-child(3) > a");
+const url = web.getUrl();
+assert.equal("https://en.wikipedia.org/wiki/Main_Page", url);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/closeWindowPass.js b/e2e/tests/web/tests/closeWindowPass.js
new file mode 100644
index 00000000..75f2266b
--- /dev/null
+++ b/e2e/tests/web/tests/closeWindowPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.closeWindow();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/deleteCookiesFail.js b/e2e/tests/web/tests/deleteCookiesFail.js
new file mode 100644
index 00000000..c812fcc3
--- /dev/null
+++ b/e2e/tests/web/tests/deleteCookiesFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.deleteCookies();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/deselectFail.js b/e2e/tests/web/tests/deselectFail.js
new file mode 100644
index 00000000..721de6cb
--- /dev/null
+++ b/e2e/tests/web/tests/deselectFail.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+const opt = opts[1];
+const value = opt.getValue();
+web.deselect("id=searchLanguage","value="+value+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/deselectPass.js b/e2e/tests/web/tests/deselectPass.js
new file mode 100644
index 00000000..cfae1ccd
--- /dev/null
+++ b/e2e/tests/web/tests/deselectPass.js
@@ -0,0 +1,9 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+const opt = opts[1];
+const value = opt.getValue();
+web.deselect("id=searchLanguage","value="+value);
+web.assertSelectedValue("id=searchLanguage", value, 600, false);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/disposePass.js b/e2e/tests/web/tests/disposePass.js
new file mode 100644
index 00000000..bf29f869
--- /dev/null
+++ b/e2e/tests/web/tests/disposePass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.dispose();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/doubleClickFail.js b/e2e/tests/web/tests/doubleClickFail.js
new file mode 100644
index 00000000..82a57310
--- /dev/null
+++ b/e2e/tests/web/tests/doubleClickFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.doubleClick("#not-valid-selector");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/doubleClickPass.js b/e2e/tests/web/tests/doubleClickPass.js
new file mode 100644
index 00000000..09ecf6fc
--- /dev/null
+++ b/e2e/tests/web/tests/doubleClickPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.doubleClick("#search-form > fieldset > button");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/dragAndDropFail.js b/e2e/tests/web/tests/dragAndDropFail.js
new file mode 100644
index 00000000..7496b8b5
--- /dev/null
+++ b/e2e/tests/web/tests/dragAndDropFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("http://demo.guru99.com/test/drag_drop.html");
+web.dragAndDrop("//*[@id='not-valid-credit2']/a", "//*[@id='not-valid-bank']/li");
diff --git a/e2e/tests/web/tests/dragAndDropPass.js b/e2e/tests/web/tests/dragAndDropPass.js
new file mode 100644
index 00000000..23cb11dc
--- /dev/null
+++ b/e2e/tests/web/tests/dragAndDropPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("http://demo.guru99.com/test/drag_drop.html");
+web.dragAndDrop("//*[@id='credit2']/a", "//*[@id='bank']/li");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/fileBrowsePass.js b/e2e/tests/web/tests/fileBrowsePass.js
new file mode 100644
index 00000000..401ee44a
--- /dev/null
+++ b/e2e/tests/web/tests/fileBrowsePass.js
@@ -0,0 +1,8 @@
+const path = require("path");
+web.init();
+web.setTimeout(6000);
+web.open("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_file");
+web.selectFrame('id=iframeResult');
+const fileName = 'assets/image.jpg';
+const filePath = path.resolve(__dirname, '..' , fileName);
+web.fileBrowse("id=myfile", filePath);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/findElementsFail.js b/e2e/tests/web/tests/findElementsFail.js
new file mode 100644
index 00000000..8f97a249
--- /dev/null
+++ b/e2e/tests/web/tests/findElementsFail.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const elements = web.findElements("#not-valid-selector");
+const elementsCorrect = elements && Array.isArray(elements) && elements.length > 0;
+assert.equal(elementsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/findElementsPass.js b/e2e/tests/web/tests/findElementsPass.js
new file mode 100644
index 00000000..774f789e
--- /dev/null
+++ b/e2e/tests/web/tests/findElementsPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const elements = web.findElements("#www-wikipedia-org > div.central-featured > div.central-featured-lang");
+const elementsCorrect = elements && Array.isArray(elements) && elements.length > 0;
+assert.equal(elementsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getAlertTextFail.js b/e2e/tests/web/tests/getAlertTextFail.js
new file mode 100644
index 00000000..c100e170
--- /dev/null
+++ b/e2e/tests/web/tests/getAlertTextFail.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+const text = web.getAlertText();
+assert.equal(text, 'p-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getAlertTextPass.js b/e2e/tests/web/tests/getAlertTextPass.js
new file mode 100644
index 00000000..088238e2
--- /dev/null
+++ b/e2e/tests/web/tests/getAlertTextPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+const text = web.getAlertText();
+assert.equal(text, 'p');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getAttributeFail.js b/e2e/tests/web/tests/getAttributeFail.js
new file mode 100644
index 00000000..4e95398a
--- /dev/null
+++ b/e2e/tests/web/tests/getAttributeFail.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const retVal = web.getAttribute("id=searchLanguage-not-valid","value");
+
+const retValCorrect = retVal && typeof retVal === 'string' && retVal.length > 0;
+assert.equal(retValCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getAttributePass.js b/e2e/tests/web/tests/getAttributePass.js
new file mode 100644
index 00000000..01be7d7d
--- /dev/null
+++ b/e2e/tests/web/tests/getAttributePass.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const retVal = web.getAttribute("id=searchLanguage","value");
+
+const retValCorrect = retVal && typeof retVal === 'string' && retVal.length > 0;
+assert.equal(retValCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getBrowserLogsPass.js b/e2e/tests/web/tests/getBrowserLogsPass.js
new file mode 100644
index 00000000..7b9c8ad0
--- /dev/null
+++ b/e2e/tests/web/tests/getBrowserLogsPass.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+
+const logs = web.getBrowserLogs();
+const logsCorrect = logs && Array.isArray(logs) && logs.length > 0;
+assert.equal(logsCorrect, true);
diff --git a/e2e/tests/web/tests/getCapabilitiesFail.js b/e2e/tests/web/tests/getCapabilitiesFail.js
new file mode 100644
index 00000000..f97314f6
--- /dev/null
+++ b/e2e/tests/web/tests/getCapabilitiesFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+const caps = web.getCapabilities();
+assert.equal(caps, {} , 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getCapabilitiesPass.js b/e2e/tests/web/tests/getCapabilitiesPass.js
new file mode 100644
index 00000000..68f1e0ce
--- /dev/null
+++ b/e2e/tests/web/tests/getCapabilitiesPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+const caps = web.getCapabilities();
+assert.equal(JSON.stringify(caps), JSON.stringify({ browserName: 'chrome' }), 'Caps not valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getCookiesPass.js b/e2e/tests/web/tests/getCookiesPass.js
new file mode 100644
index 00000000..52a03d2c
--- /dev/null
+++ b/e2e/tests/web/tests/getCookiesPass.js
@@ -0,0 +1,13 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const cookies = web.getCookies();
+
+const goodCookies = cookies && Array.isArray(cookies) && cookies.length > 0;
+assert.equal(goodCookies, true);
+
+cookies.map(({name}) => web.deleteCookies(name));
+
+const cookiesAfterDelete = web.getCookies();
+const goodDeletedCookies = cookiesAfterDelete && Array.isArray(cookiesAfterDelete) && cookiesAfterDelete.length === 0;
+assert.equal(goodDeletedCookies, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getCssValueFail.js b/e2e/tests/web/tests/getCssValueFail.js
new file mode 100644
index 00000000..6dffd9ae
--- /dev/null
+++ b/e2e/tests/web/tests/getCssValueFail.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const color = web.getCssValue(caps.h1Strong);
+const validColor = color && typeof color === 'string' && color === 'rgba(0,0,0,1)';
+assert.equal(validColor, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getCssValuePass.js b/e2e/tests/web/tests/getCssValuePass.js
new file mode 100644
index 00000000..b17ffabd
--- /dev/null
+++ b/e2e/tests/web/tests/getCssValuePass.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const color = web.getCssValue(caps.h1Strong, "color");
+const validColor = color && typeof color === 'string' && color === 'rgba(0,0,0,1)';
+assert.equal(validColor, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getElementCountPass.js b/e2e/tests/web/tests/getElementCountPass.js
new file mode 100644
index 00000000..d6a09dd6
--- /dev/null
+++ b/e2e/tests/web/tests/getElementCountPass.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const count = web.getElementCount("#www-wikipedia-org > div.central-featured > div.central-featured-lang");
+assert.equal(count, 10);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getPageSourcePass.js b/e2e/tests/web/tests/getPageSourcePass.js
new file mode 100644
index 00000000..03fdd20b
--- /dev/null
+++ b/e2e/tests/web/tests/getPageSourcePass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.wikipedia.org/');
+const source = web.getSource();
+const sourceCorrect = source && typeof source === 'string' && source.length > 0;
+assert.equal(sourceCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getWindowHandlesPass.js b/e2e/tests/web/tests/getWindowHandlesPass.js
new file mode 100644
index 00000000..aa793a8a
--- /dev/null
+++ b/e2e/tests/web/tests/getWindowHandlesPass.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+web.selectFrame('id=iframeResult');
+web.click('/html/body/a');
+const handles = web.getWindowHandles();
+const handlesCorrect = handles && Array.isArray(handles) && handles.length > 0 && handles.length === 2;
+assert.equal(handlesCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/getXMLPageSourceFail.js b/e2e/tests/web/tests/getXMLPageSourceFail.js
new file mode 100644
index 00000000..de1f5a2d
--- /dev/null
+++ b/e2e/tests/web/tests/getXMLPageSourceFail.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const source = web.getXMLPageSource();
+
+const validSourse = source && typeof source === 'string' && source.length > 0;
+assert.equal(validSourse, true);
diff --git a/e2e/tests/web/tests/getXMLPageSourcePass.js b/e2e/tests/web/tests/getXMLPageSourcePass.js
new file mode 100644
index 00000000..320c9aed
--- /dev/null
+++ b/e2e/tests/web/tests/getXMLPageSourcePass.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.w3schools.com/xml/note.xml");
+const source = web.getXMLPageSource();
+
+const validSourse = source && typeof source === 'string' && source.length > 0;
+assert.equal(validSourse, true);
diff --git a/e2e/tests/web/tests/initPass.js b/e2e/tests/web/tests/initPass.js
new file mode 100644
index 00000000..1a78808d
--- /dev/null
+++ b/e2e/tests/web/tests/initPass.js
@@ -0,0 +1 @@
+web.init();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isAlertPresentFail.js b/e2e/tests/web/tests/isAlertPresentFail.js
new file mode 100644
index 00000000..550a05f2
--- /dev/null
+++ b/e2e/tests/web/tests/isAlertPresentFail.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+const present = web.isAlertPresent();
+assert.equal(present, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isAlertPresentPass.js b/e2e/tests/web/tests/isAlertPresentPass.js
new file mode 100644
index 00000000..d78a3bc6
--- /dev/null
+++ b/e2e/tests/web/tests/isAlertPresentPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("wikipedia.org");
+web.execute(function(p){ alert('p');});
+const present = web.isAlertPresent();
+assert.equal(present, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isExistFail.js b/e2e/tests/web/tests/isExistFail.js
new file mode 100644
index 00000000..922377e6
--- /dev/null
+++ b/e2e/tests/web/tests/isExistFail.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const isExist = web.isExist("id=searchLanguage-not-valid");
+assert.equal(isExist, fail);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isExistPass.js b/e2e/tests/web/tests/isExistPass.js
new file mode 100644
index 00000000..79b8b287
--- /dev/null
+++ b/e2e/tests/web/tests/isExistPass.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const isExist = web.isExist("id=searchLanguage");
+assert.equal(isExist, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isVisibleFail.js b/e2e/tests/web/tests/isVisibleFail.js
new file mode 100644
index 00000000..44251155
--- /dev/null
+++ b/e2e/tests/web/tests/isVisibleFail.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const visible = web.isVisible("#searchLanguage > option:nth-child(24)");
+assert.equal(visible, true);
+
+const visible2 = web.isVisible(caps.h1Strong);
+assert.equal(visible2, false);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/isVisiblePass.js b/e2e/tests/web/tests/isVisiblePass.js
new file mode 100644
index 00000000..1a55eb50
--- /dev/null
+++ b/e2e/tests/web/tests/isVisiblePass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const visible = web.isVisible("#searchLanguage > option:nth-child(24)");
+assert.equal(visible, false);
+
+
+const visible2 = web.isVisible(caps.h1Strong);
+assert.equal(visible2, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/makeVisibleFail.js b/e2e/tests/web/tests/makeVisibleFail.js
new file mode 100644
index 00000000..49443ff6
--- /dev/null
+++ b/e2e/tests/web/tests/makeVisibleFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.makeVisible("id=searchLanguage-not-valid");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/makeVisiblePass.js b/e2e/tests/web/tests/makeVisiblePass.js
new file mode 100644
index 00000000..0a6e1775
--- /dev/null
+++ b/e2e/tests/web/tests/makeVisiblePass.js
@@ -0,0 +1,11 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+
+const visible = web.isVisible("id=searchLanguage");
+assert.equal(visible, false);
+
+web.makeVisible("id=searchLanguage");
+
+const visible2 = web.isVisible("id=searchLanguage");
+assert.equal(visible2, true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/openPass.js b/e2e/tests/web/tests/openPass.js
new file mode 100644
index 00000000..589b4596
--- /dev/null
+++ b/e2e/tests/web/tests/openPass.js
@@ -0,0 +1,3 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.wikipedia.org/');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/pointFail.js b/e2e/tests/web/tests/pointFail.js
new file mode 100644
index 00000000..50d39e42
--- /dev/null
+++ b/e2e/tests/web/tests/pointFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.point("#www-wikipedia-org > p > small:nth-child(3) > a");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/pointPass.js b/e2e/tests/web/tests/pointPass.js
new file mode 100644
index 00000000..6b4fff6f
--- /dev/null
+++ b/e2e/tests/web/tests/pointPass.js
@@ -0,0 +1,5 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.scrollToElement("#www-wikipedia-org > p > small:nth-child(3) > a", true);
+web.point("#www-wikipedia-org > p > small:nth-child(3) > a");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/refreshPass.js b/e2e/tests/web/tests/refreshPass.js
new file mode 100644
index 00000000..902ce7fb
--- /dev/null
+++ b/e2e/tests/web/tests/refreshPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.refresh();
\ No newline at end of file
diff --git a/e2e/tests/web/tests/rightClickFail.js b/e2e/tests/web/tests/rightClickFail.js
new file mode 100644
index 00000000..9a77a192
--- /dev/null
+++ b/e2e/tests/web/tests/rightClickFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.rightClick("id=not-valid");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/rightClickPass.js b/e2e/tests/web/tests/rightClickPass.js
new file mode 100644
index 00000000..3c5f50f8
--- /dev/null
+++ b/e2e/tests/web/tests/rightClickPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.rightClick("#www-wikipedia-org > p > small:nth-child(3) > a");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/scrollToElementFail.js b/e2e/tests/web/tests/scrollToElementFail.js
new file mode 100644
index 00000000..c9304ca2
--- /dev/null
+++ b/e2e/tests/web/tests/scrollToElementFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.scrollToElement("id=not-valid", true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/scrollToElementPass.js b/e2e/tests/web/tests/scrollToElementPass.js
new file mode 100644
index 00000000..a6a80f5b
--- /dev/null
+++ b/e2e/tests/web/tests/scrollToElementPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.scrollToElement("#www-wikipedia-org > p > small:nth-child(3) > a", true);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/selectFail.js b/e2e/tests/web/tests/selectFail.js
new file mode 100644
index 00000000..3e50f9c1
--- /dev/null
+++ b/e2e/tests/web/tests/selectFail.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+const opt = opts[1];
+const value = opt.getValue();
+web.select("id=searchLanguage","value="+value+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/selectPass.js b/e2e/tests/web/tests/selectPass.js
new file mode 100644
index 00000000..7bc39dd4
--- /dev/null
+++ b/e2e/tests/web/tests/selectPass.js
@@ -0,0 +1,9 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const element = web.findElement("id=searchLanguage");
+const opts = element.$$('//option');
+const opt = opts[1];
+const value = opt.getValue();
+web.select("id=searchLanguage","value="+value);
+web.assertSelectedValue("id=searchLanguage", value, 600, false);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/selectWindowFail.js b/e2e/tests/web/tests/selectWindowFail.js
new file mode 100644
index 00000000..8796ec9b
--- /dev/null
+++ b/e2e/tests/web/tests/selectWindowFail.js
@@ -0,0 +1,10 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+
+const title = web.getTitle();
+
+web.selectFrame('id=iframeResult');
+web.click('/html/body/a');
+
+web.selectWindow("title="+title+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/selectWindowPass.js b/e2e/tests/web/tests/selectWindowPass.js
new file mode 100644
index 00000000..fd62667d
--- /dev/null
+++ b/e2e/tests/web/tests/selectWindowPass.js
@@ -0,0 +1,10 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+
+const title = web.getTitle();
+
+web.selectFrame('id=iframeResult');
+web.click('/html/body/a');
+
+web.selectWindow("title="+title);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/sendKeysPass.js b/e2e/tests/web/tests/sendKeysPass.js
new file mode 100644
index 00000000..75d6e25a
--- /dev/null
+++ b/e2e/tests/web/tests/sendKeysPass.js
@@ -0,0 +1,8 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+web.sendKeys("Enter");
+
+const url = web.getUrl();
+assert.notEqual("https://www.wikipedia.org/", url);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/setGetWindowSizePass.js b/e2e/tests/web/tests/setGetWindowSizePass.js
new file mode 100644
index 00000000..de72c65d
--- /dev/null
+++ b/e2e/tests/web/tests/setGetWindowSizePass.js
@@ -0,0 +1,7 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.setWindowSize(600, 600);
+const sizeObject = web.getWindowSize();
+assert.equal(sizeObject.height, 600);
+assert.equal(sizeObject.width, 600);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/setTimeoutFail.js b/e2e/tests/web/tests/setTimeoutFail.js
new file mode 100644
index 00000000..7b951086
--- /dev/null
+++ b/e2e/tests/web/tests/setTimeoutFail.js
@@ -0,0 +1,2 @@
+web.init();
+web.setTimeout('6000');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/setTimeoutPass.js b/e2e/tests/web/tests/setTimeoutPass.js
new file mode 100644
index 00000000..befbe560
--- /dev/null
+++ b/e2e/tests/web/tests/setTimeoutPass.js
@@ -0,0 +1,2 @@
+web.init();
+web.setTimeout(6000);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/setWindowSizeFail.js b/e2e/tests/web/tests/setWindowSizeFail.js
new file mode 100644
index 00000000..26e43f3e
--- /dev/null
+++ b/e2e/tests/web/tests/setWindowSizeFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.setWindowSize('600', '600');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/takeScreenshotPass.js b/e2e/tests/web/tests/takeScreenshotPass.js
new file mode 100644
index 00000000..34b319a9
--- /dev/null
+++ b/e2e/tests/web/tests/takeScreenshotPass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+const screen = web.takeScreenshot();
+const screenCorrect = screen && typeof screen === 'string' && screen.length > 0;
+assert.equal(screenCorrect, true);
diff --git a/e2e/tests/web/tests/transaction.js b/e2e/tests/web/tests/transaction.js
new file mode 100644
index 00000000..2ffa8231
--- /dev/null
+++ b/e2e/tests/web/tests/transaction.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.transaction('transaction');
+web.open('wikipedia.org');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/typeFail.js b/e2e/tests/web/tests/typeFail.js
new file mode 100644
index 00000000..bd426c33
--- /dev/null
+++ b/e2e/tests/web/tests/typeFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=not-valid-id", "wiki");
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForExistFail.js b/e2e/tests/web/tests/waitForExistFail.js
new file mode 100644
index 00000000..f2c275f6
--- /dev/null
+++ b/e2e/tests/web/tests/waitForExistFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForExist('#not-valid-element');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForExistPass.js b/e2e/tests/web/tests/waitForExistPass.js
new file mode 100644
index 00000000..5179fb77
--- /dev/null
+++ b/e2e/tests/web/tests/waitForExistPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForExist(caps.h1Strong)
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotExistFail.js b/e2e/tests/web/tests/waitForNotExistFail.js
new file mode 100644
index 00000000..97fc0623
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotExistFail.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForNotExist(caps.h1Strong)
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotExistPass.js b/e2e/tests/web/tests/waitForNotExistPass.js
new file mode 100644
index 00000000..444342a7
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotExistPass.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForNotExist('#not-valid-element');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotTextFail.js b/e2e/tests/web/tests/waitForNotTextFail.js
new file mode 100644
index 00000000..29455f52
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotTextFail.js
@@ -0,0 +1,12 @@
+const selector = '#www-wikipedia-org > div.central-textlogo > h1 > span';
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+
+web.waitForVisible(selector);
+
+const textElement = web.findElement(selector);
+const text = web.getText(textElement);
+
+web.waitForNotText(selector, text);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotTextPass.js b/e2e/tests/web/tests/waitForNotTextPass.js
new file mode 100644
index 00000000..89581b88
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotTextPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const textElem = web.findElement(caps.h1Strong);
+
+const text = web.getText(textElem);
+
+web.waitForNotText(caps.h1Strong, text+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotValueFail.js b/e2e/tests/web/tests/waitForNotValueFail.js
new file mode 100644
index 00000000..69d037c3
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotValueFail.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+const value = web.getValue("id=searchInput");
+web.waitForNotValue("id=searchInput", value);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForNotValuePass.js b/e2e/tests/web/tests/waitForNotValuePass.js
new file mode 100644
index 00000000..35697c44
--- /dev/null
+++ b/e2e/tests/web/tests/waitForNotValuePass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+const value = web.getValue("id=searchInput");
+web.waitForNotValue("id=searchInput", value+'-now-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForTextFail.js b/e2e/tests/web/tests/waitForTextFail.js
new file mode 100644
index 00000000..dfb5842e
--- /dev/null
+++ b/e2e/tests/web/tests/waitForTextFail.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const text = web.findElement(caps.h1Strong);
+web.waitForText(caps.h1Strong, text.getText()+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForTextPass.js b/e2e/tests/web/tests/waitForTextPass.js
new file mode 100644
index 00000000..f32b98cd
--- /dev/null
+++ b/e2e/tests/web/tests/waitForTextPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+const textElem = web.findElement(caps.h1Strong);
+
+const text = web.getText(textElem);
+
+web.waitForText(caps.h1Strong, text);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForValueFail.js b/e2e/tests/web/tests/waitForValueFail.js
new file mode 100644
index 00000000..5fc5976b
--- /dev/null
+++ b/e2e/tests/web/tests/waitForValueFail.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+const value = web.getValue("id=searchInput");
+web.waitForValue("id=searchInput", value+'-now-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForValuePass.js b/e2e/tests/web/tests/waitForValuePass.js
new file mode 100644
index 00000000..52087b28
--- /dev/null
+++ b/e2e/tests/web/tests/waitForValuePass.js
@@ -0,0 +1,6 @@
+web.init();
+web.setTimeout(6000);
+web.open("https://www.wikipedia.org/");
+web.type("id=searchInput", "wiki");
+const value = web.getValue("id=searchInput");
+web.waitForValue("id=searchInput", value);
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForVisibleFail.js b/e2e/tests/web/tests/waitForVisibleFail.js
new file mode 100644
index 00000000..0dcc55a4
--- /dev/null
+++ b/e2e/tests/web/tests/waitForVisibleFail.js
@@ -0,0 +1,4 @@
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForVisible('#not-valid-element');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForVisiblePass.js b/e2e/tests/web/tests/waitForVisiblePass.js
new file mode 100644
index 00000000..95b7272f
--- /dev/null
+++ b/e2e/tests/web/tests/waitForVisiblePass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+
+web.init();
+web.setTimeout(6000);
+web.open('wikipedia.org');
+web.waitForVisible(caps.h1Strong)
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForWindowFail.js b/e2e/tests/web/tests/waitForWindowFail.js
new file mode 100644
index 00000000..861595f7
--- /dev/null
+++ b/e2e/tests/web/tests/waitForWindowFail.js
@@ -0,0 +1,10 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+
+const title = web.getTitle();
+
+web.selectFrame('id=iframeResult');
+web.click('/html/body/a');
+
+web.waitForWindow("title="+title+'-not-valid');
\ No newline at end of file
diff --git a/e2e/tests/web/tests/waitForWindowPass.js b/e2e/tests/web/tests/waitForWindowPass.js
new file mode 100644
index 00000000..8a1fd2a9
--- /dev/null
+++ b/e2e/tests/web/tests/waitForWindowPass.js
@@ -0,0 +1,10 @@
+web.init();
+web.setTimeout(6000);
+web.open('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_link_target');
+
+const title = web.getTitle();
+
+web.selectFrame('id=iframeResult');
+web.click('/html/body/a');
+
+web.waitForWindow("title="+title);
\ No newline at end of file
diff --git a/e2e/tests/win.js b/e2e/tests/win.js
new file mode 100644
index 00000000..c96bbacd
--- /dev/null
+++ b/e2e/tests/win.js
@@ -0,0 +1,154 @@
+const cmd = require('../tools/cmd');
+const { shouldPass, shouldFail } = require('../tools/resultHelper');
+const config = require('../tools/config.js');
+const mocha = require('mocha');
+const describe = mocha.describe;
+const it = mocha.it;
+
+const afterStart = config.afterStart;
+const testsFolder = '/win/tests/';
+const startPath = afterStart+testsFolder;
+
+const cliProcess = cmd.create(config.start, startPath, '.');
+
+describe('win-module-single', () => {
+ it('[getCapabilities] correct', async () => {
+ const response = await cliProcess.execute('win.getCapabilitiesPass.js');
+ shouldPass(response);
+ });
+
+ it('[init] correct', async () => {
+ const response = await cliProcess.execute('win.initPass.js');
+ shouldPass(response);
+ });
+
+ it('[pause] correct', async () => {
+ const response = await cliProcess.execute('win.pausePass.js');
+ shouldPass(response);
+ });
+
+ it('[dispose] correct', async () => {
+ const response = await cliProcess.execute('win.disposePass.js');
+ shouldPass(response);
+ });
+
+ it('[transaction] correct', async () => {
+ const response = await cliProcess.execute('win.transactionPass.js');
+ shouldPass(response);
+ });
+
+ it('[open] not correct', async () => {
+ const response = await cliProcess.execute('win.openFail.js');
+ shouldFail(response);
+ });
+
+ it('[setTimeout] correct', async () => {
+ const response = await cliProcess.execute('win.setTimeoutPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertText] correct', async () => {
+ const response = await cliProcess.execute('win.assertTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[assertTitle] correct', async () => {
+ const response = await cliProcess.execute('win.assertTitlePass.js');
+ shouldPass(response);
+ });
+
+ it('[takeScreenshot] correct', async () => {
+ const response = await cliProcess.execute('win.takeScreenshotPass.js');
+ shouldPass(response);
+ });
+
+ it('[getSource] correct', async () => {
+ const response = await cliProcess.execute('win.getSourcePass.js');
+ shouldPass(response);
+ });
+
+ it('[getAppiumLogs] not correct', async () => {
+ const response = await cliProcess.execute('win.getAppiumLogsFail.js');
+ shouldFail(response);
+ });
+
+ it('[click] correct', async () => {
+ const response = await cliProcess.execute('win.clickPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForExist] correct', async () => {
+ const response = await cliProcess.execute('win.waitForExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[waitForVisible] correct', async () => {
+ const response = await cliProcess.execute('win.waitForVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[getLocation] not correct', async () => {
+ const response = await cliProcess.execute('win.getLocationFail.js');
+ shouldFail(response);
+ });
+
+ it('[isVisible] not correct', async () => {
+ const response = await cliProcess.execute('win.isVisiblePass.js');
+ shouldPass(response);
+ });
+
+ it('[isExist] not correct', async () => {
+ const response = await cliProcess.execute('win.isExistPass.js');
+ shouldPass(response);
+ });
+
+ it('[findElement] correct', async () => {
+ const response = await cliProcess.execute('win.findElementPass.js');
+ shouldPass(response);
+ });
+
+ it('[findElements] correct', async () => {
+ const response = await cliProcess.execute('win.findElementsPass.js');
+ shouldPass(response);
+ });
+
+ it('[clear] correct', async () => {
+ const response = await cliProcess.execute('win.clearPass.js');
+ shouldPass(response);
+ });
+
+ it('[getText] correct', async () => {
+ const response = await cliProcess.execute('win.getTextPass.js');
+ shouldPass(response);
+ });
+
+ it('[type] correct', async () => {
+ const response = await cliProcess.execute('win.typePass.js');
+ shouldPass(response);
+ });
+
+ it('[isSelected] correct', async () => {
+ const response = await cliProcess.execute('win.isSelectedPass.js');
+ shouldPass(response);
+ });
+
+ it('[sendKeys] not correct', async () => {
+ const response = await cliProcess.execute('win.sendKeysFail.js');
+ shouldFail(response);
+ });
+
+ it('[clickLong] not correct', async () => {
+ const response = await cliProcess.execute('win.clickLongPass.js');
+ shouldPass(response);
+ });
+
+ it('[clickMultipleTimes] not correct', async () => {
+ const response = await cliProcess.execute('win.clickMultipleTimesPass.js');
+ shouldPass(response);
+ });
+
+ it('[rightClick] not correct', async () => {
+ const response = await cliProcess.execute('win.rightClickPass.js');
+ shouldPass(response);
+ });
+});
diff --git a/e2e/tests/win/assets/caps.js b/e2e/tests/win/assets/caps.js
new file mode 100644
index 00000000..51f92fb7
--- /dev/null
+++ b/e2e/tests/win/assets/caps.js
@@ -0,0 +1,3 @@
+module.exports = {
+
+}
\ No newline at end of file
diff --git a/e2e/tests/win/assets/grepWin.exe b/e2e/tests/win/assets/grepWin.exe
new file mode 100644
index 00000000..0c72d2d0
Binary files /dev/null and b/e2e/tests/win/assets/grepWin.exe differ
diff --git a/e2e/tests/win/tests/win.assertTextPass.js b/e2e/tests/win/tests/win.assertTextPass.js
new file mode 100644
index 00000000..453eaf49
--- /dev/null
+++ b/e2e/tests/win/tests/win.assertTextPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.assertText('/Window/Text[9]', 'Press F1 for help');
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.assertTitlePass.js b/e2e/tests/win/tests/win.assertTitlePass.js
new file mode 100644
index 00000000..708fdfc2
--- /dev/null
+++ b/e2e/tests/win/tests/win.assertTitlePass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.assertTitle('grepWin');
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.assertValuePass.js b/e2e/tests/win/tests/win.assertValuePass.js
new file mode 100644
index 00000000..7c453553
--- /dev/null
+++ b/e2e/tests/win/tests/win.assertValuePass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
diff --git a/e2e/tests/win/tests/win.backPass.js b/e2e/tests/win/tests/win.backPass.js
new file mode 100644
index 00000000..25b677d6
--- /dev/null
+++ b/e2e/tests/win/tests/win.backPass.js
@@ -0,0 +1,13 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.WindowsAlarms_8wekyb3d8bbwe!App';
+win.init(caps);
+
+win.click('/Window/Window[2]/List/ListItem[1]');
+
+win.pause(15000);
+
+win.click('/Window/Window[2]/List/ListItem[3]');
+
+win.pause(5000);
+
+win.back();
diff --git a/e2e/tests/win/tests/win.clearPass.js b/e2e/tests/win/tests/win.clearPass.js
new file mode 100644
index 00000000..e4fd1772
--- /dev/null
+++ b/e2e/tests/win/tests/win.clearPass.js
@@ -0,0 +1,29 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.BingWeather_8wekyb3d8bbwe!App';
+caps.fullReset = true;
+win.init(caps);
+
+win.pause(5000);
+
+win.type('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit', 'London');
+
+win.pause(1000);
+
+let text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('London' === text, true);
+
+win.pause(10000);
+
+win.clear('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('' === text, true);
+
+win.pause(5000);
+
diff --git a/e2e/tests/win/tests/win.clickLongPass.js b/e2e/tests/win/tests/win.clickLongPass.js
new file mode 100644
index 00000000..3fecc502
--- /dev/null
+++ b/e2e/tests/win/tests/win.clickLongPass.js
@@ -0,0 +1,15 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.pause(1000);
+win.clickLong('/Window/Button[10]', 100);
+win.pause(1000);
+
+win.waitForExist('/Window/Window/ComboBox');
+win.waitForVisible('/Window/Window/ComboBox');
+
+win.click('/Window/Window/Button[2]');
+win.pause(3000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.clickMultipleTimesPass.js b/e2e/tests/win/tests/win.clickMultipleTimesPass.js
new file mode 100644
index 00000000..9162a636
--- /dev/null
+++ b/e2e/tests/win/tests/win.clickMultipleTimesPass.js
@@ -0,0 +1,15 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.pause(1000);
+win.clickMultipleTimes('/Window/Button[10]', 2);
+win.pause(1000);
+
+win.waitForExist('/Window/Window/ComboBox');
+win.waitForVisible('/Window/Window/ComboBox');
+
+win.click('/Window/Window/Button[2]');
+win.pause(3000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.clickPass.js b/e2e/tests/win/tests/win.clickPass.js
new file mode 100644
index 00000000..685490aa
--- /dev/null
+++ b/e2e/tests/win/tests/win.clickPass.js
@@ -0,0 +1,15 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.click('/Window/Button[10]');
+
+win.pause(3000);
+
+win.waitForExist('/Window/Window/ComboBox');
+win.waitForVisible('/Window/Window/ComboBox');
+
+win.click('/Window/Window/Button[2]');
+win.pause(3000);
diff --git a/e2e/tests/win/tests/win.disposePass.js b/e2e/tests/win/tests/win.disposePass.js
new file mode 100644
index 00000000..b54f51de
--- /dev/null
+++ b/e2e/tests/win/tests/win.disposePass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+win.pause(10000);
+win.dispose();
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.findElementPass.js b/e2e/tests/win/tests/win.findElementPass.js
new file mode 100644
index 00000000..8f784999
--- /dev/null
+++ b/e2e/tests/win/tests/win.findElementPass.js
@@ -0,0 +1,13 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const el = win.findElement('/Window/CheckBox[4]');
+log.info(el);
+
+win.pause(15000);
+
+assert.equal(!!el, true);
+
diff --git a/e2e/tests/win/tests/win.findElementsPass.js b/e2e/tests/win/tests/win.findElementsPass.js
new file mode 100644
index 00000000..0df8c97a
--- /dev/null
+++ b/e2e/tests/win/tests/win.findElementsPass.js
@@ -0,0 +1,11 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const els = win.findElements('/Window/CheckBox');
+log.info(els.length);
+
+assert.equal(els.length === 8, true);
+
diff --git a/e2e/tests/win/tests/win.getAppiumLogsFail.js b/e2e/tests/win/tests/win.getAppiumLogsFail.js
new file mode 100644
index 00000000..1e965a71
--- /dev/null
+++ b/e2e/tests/win/tests/win.getAppiumLogsFail.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const logs = win.getAppiumLogs();
+log.info(logs);
+const logsCorrect = logs && Array.isArray(logs);
+assert.equal(logsCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.getCapabilitiesPass.js b/e2e/tests/win/tests/win.getCapabilitiesPass.js
new file mode 100644
index 00000000..1690c005
--- /dev/null
+++ b/e2e/tests/win/tests/win.getCapabilitiesPass.js
@@ -0,0 +1,16 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+const capabilities = win.getCapabilities();
+log.info(capabilities);
+const capsValid =
+ !!capabilities &&
+ !!capabilities.app &&
+ !!capabilities.platformName &&
+ !!capabilities.deviceName &&
+ !!capabilities.platformVersion;
+
+
+assert.equal(capsValid, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.getLocationFail.js b/e2e/tests/win/tests/win.getLocationFail.js
new file mode 100644
index 00000000..1112a13f
--- /dev/null
+++ b/e2e/tests/win/tests/win.getLocationFail.js
@@ -0,0 +1,8 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const loc1 = win.getLocation('/Window/RadioButton[7]');
+win.tap(loc1.x,loc1.y);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.getSourcePass.js b/e2e/tests/win/tests/win.getSourcePass.js
new file mode 100644
index 00000000..6abb1d77
--- /dev/null
+++ b/e2e/tests/win/tests/win.getSourcePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const source = win.getSource();
+
+const sourceCorrect = source && typeof source === 'string' && source.length > 0;
+assert.equal(sourceCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.getTextPass.js b/e2e/tests/win/tests/win.getTextPass.js
new file mode 100644
index 00000000..5d7bb8b3
--- /dev/null
+++ b/e2e/tests/win/tests/win.getTextPass.js
@@ -0,0 +1,28 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.BingWeather_8wekyb3d8bbwe!App';
+win.init(caps);
+
+win.pause(5000);
+
+win.type('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit', 'London');
+
+win.pause(1000);
+
+let text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('London' === text, true);
+
+win.pause(10000);
+
+win.clear('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('' === text, true);
+
+win.pause(5000);
+
diff --git a/e2e/tests/win/tests/win.getValuePass.js b/e2e/tests/win/tests/win.getValuePass.js
new file mode 100644
index 00000000..20886573
--- /dev/null
+++ b/e2e/tests/win/tests/win.getValuePass.js
@@ -0,0 +1,15 @@
+
+
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.pause(5000);
+
+const value = win.getValue('/Window/ComboBox');
+const text = win.getText('/Window/ComboBox');
+
+log.info(value);
+log.info(text);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.initPass.js b/e2e/tests/win/tests/win.initPass.js
new file mode 100644
index 00000000..32fa9318
--- /dev/null
+++ b/e2e/tests/win/tests/win.initPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+win.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isCheckablePass.js b/e2e/tests/win/tests/win.isCheckablePass.js
new file mode 100644
index 00000000..98c31615
--- /dev/null
+++ b/e2e/tests/win/tests/win.isCheckablePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const checkable = win.isCheckable('/Window/RadioButton[3]');
+log.info(checkable);
+
+assert.equal(checkable, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isCheckedFail.js b/e2e/tests/win/tests/win.isCheckedFail.js
new file mode 100644
index 00000000..9b5f7f30
--- /dev/null
+++ b/e2e/tests/win/tests/win.isCheckedFail.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const checked = win.isChecked('/Window/CheckBox[4]');
+log.info(checked);
+
+assert.equal(checked, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isClickablePass.js b/e2e/tests/win/tests/win.isClickablePass.js
new file mode 100644
index 00000000..05bfa90a
--- /dev/null
+++ b/e2e/tests/win/tests/win.isClickablePass.js
@@ -0,0 +1,12 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.pause(5000);
+
+const clickable = win.isClickable('/Window/Button[12]');
+log.info(clickable);
+
+assert.equal(clickable, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isExistPass.js b/e2e/tests/win/tests/win.isExistPass.js
new file mode 100644
index 00000000..cf22ea80
--- /dev/null
+++ b/e2e/tests/win/tests/win.isExistPass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const exist = win.isExist('/Window/RadioButton[1]');
+log.info(exist);
+
+assert.equal(exist, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isSelectedPass.js b/e2e/tests/win/tests/win.isSelectedPass.js
new file mode 100644
index 00000000..51b9fd44
--- /dev/null
+++ b/e2e/tests/win/tests/win.isSelectedPass.js
@@ -0,0 +1,13 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.BingWeather_8wekyb3d8bbwe!App';
+win.init(caps);
+
+win.pause(5000);
+
+const selected1 = win.isSelected('/Window/Window[2]/Custom[4]/Group/List/Pane/RadioButton[1]');
+const selected2 = win.isSelected('/Window/Window[2]/Custom[4]/Group/List/Pane/RadioButton[2]');
+
+log.info(selected1);
+log.info(selected2);
+
+assert.equal(selected1 || selected2, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.isVisiblePass.js b/e2e/tests/win/tests/win.isVisiblePass.js
new file mode 100644
index 00000000..d7ac417b
--- /dev/null
+++ b/e2e/tests/win/tests/win.isVisiblePass.js
@@ -0,0 +1,10 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const visible = win.isVisible('/Window/RadioButton[1]');
+log.info(visible);
+
+assert.equal(visible, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.openFail.js b/e2e/tests/win/tests/win.openFail.js
new file mode 100644
index 00000000..4347016e
--- /dev/null
+++ b/e2e/tests/win/tests/win.openFail.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+// const path = require('path');
+// const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+// caps.app = apkPath;
+win.init(caps);
+win.open('https://www.wikipedia.org');
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.pausePass.js b/e2e/tests/win/tests/win.pausePass.js
new file mode 100644
index 00000000..32fa9318
--- /dev/null
+++ b/e2e/tests/win/tests/win.pausePass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+win.pause(10000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.rightClickPass.js b/e2e/tests/win/tests/win.rightClickPass.js
new file mode 100644
index 00000000..36f2f1aa
--- /dev/null
+++ b/e2e/tests/win/tests/win.rightClickPass.js
@@ -0,0 +1,7 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.rightClick('/Window/Edit[4]');
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.sendKeysFail.js b/e2e/tests/win/tests/win.sendKeysFail.js
new file mode 100644
index 00000000..2df839c1
--- /dev/null
+++ b/e2e/tests/win/tests/win.sendKeysFail.js
@@ -0,0 +1,23 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.BingWeather_8wekyb3d8bbwe!App';
+caps.fullReset = true;
+win.init(caps);
+
+win.pause(2000);
+
+win.type('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit', 'London');
+
+win.pause(2000);
+
+let text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('London' === text, true);
+
+win.pause(2000);
+
+win.sendKeys("Enter");
+
+
+win.pause(20000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.setTimeoutPass.js b/e2e/tests/win/tests/win.setTimeoutPass.js
new file mode 100644
index 00000000..4f8d53cf
--- /dev/null
+++ b/e2e/tests/win/tests/win.setTimeoutPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+win.setTimeout(6000);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.takeScreenshotPass.js b/e2e/tests/win/tests/win.takeScreenshotPass.js
new file mode 100644
index 00000000..3e4cc7f8
--- /dev/null
+++ b/e2e/tests/win/tests/win.takeScreenshotPass.js
@@ -0,0 +1,9 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+const screen = win.takeScreenshot();
+const screenCorrect = screen && typeof screen === 'string' && screen.length > 0;
+assert.equal(screenCorrect, true);
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.transactionPass.js b/e2e/tests/win/tests/win.transactionPass.js
new file mode 100644
index 00000000..ee0edd08
--- /dev/null
+++ b/e2e/tests/win/tests/win.transactionPass.js
@@ -0,0 +1,6 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+win.transaction('transaction');
\ No newline at end of file
diff --git a/e2e/tests/win/tests/win.typePass.js b/e2e/tests/win/tests/win.typePass.js
new file mode 100644
index 00000000..5d7bb8b3
--- /dev/null
+++ b/e2e/tests/win/tests/win.typePass.js
@@ -0,0 +1,28 @@
+const caps = require('../assets/caps');
+caps.app = 'Microsoft.BingWeather_8wekyb3d8bbwe!App';
+win.init(caps);
+
+win.pause(5000);
+
+win.type('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit', 'London');
+
+win.pause(1000);
+
+let text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('London' === text, true);
+
+win.pause(10000);
+
+win.clear('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+text = win.getText('/Window/Window[2]/Custom[4]/Group/List/Pane/Group/Edit');
+
+log.info(text);
+
+assert.equal('' === text, true);
+
+win.pause(5000);
+
diff --git a/e2e/tests/win/tests/win.waitForExistPass.js b/e2e/tests/win/tests/win.waitForExistPass.js
new file mode 100644
index 00000000..685490aa
--- /dev/null
+++ b/e2e/tests/win/tests/win.waitForExistPass.js
@@ -0,0 +1,15 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.click('/Window/Button[10]');
+
+win.pause(3000);
+
+win.waitForExist('/Window/Window/ComboBox');
+win.waitForVisible('/Window/Window/ComboBox');
+
+win.click('/Window/Window/Button[2]');
+win.pause(3000);
diff --git a/e2e/tests/win/tests/win.waitForVisiblePass.js b/e2e/tests/win/tests/win.waitForVisiblePass.js
new file mode 100644
index 00000000..e33bb0bf
--- /dev/null
+++ b/e2e/tests/win/tests/win.waitForVisiblePass.js
@@ -0,0 +1,16 @@
+const caps = require('../assets/caps');
+const path = require('path');
+const apkPath = path.resolve(__dirname, '../assets/grepWin.exe');
+caps.app = apkPath;
+win.init(caps);
+
+win.click('/Window/Button[10]');
+
+win.pause(3000);
+
+win.waitForExist('/Window/Window/ComboBox');
+win.waitForVisible('/Window/Window/ComboBox');
+
+win.click('/Window/Window/Button[2]');
+win.pause(3000);
+
diff --git a/e2e/tools/cmd.js b/e2e/tools/cmd.js
new file mode 100644
index 00000000..7619f237
--- /dev/null
+++ b/e2e/tools/cmd.js
@@ -0,0 +1,177 @@
+/**
+ * Integration test helper
+ * Author: Andrés Zorro
+ */
+
+const { existsSync } = require('fs');
+const { constants } = require('os');
+const spawn = require('cross-spawn');
+const concat = require('concat-stream');
+
+/**
+ * Creates a child process with script path
+ * @param {string} processPath Path of the process to execute
+ * @param {Array} args Arguments to the command
+ * @param {Object} env (optional) Environment variables
+ */
+function createProcess(processPath, startPath, args = [], env = null) {
+ // Ensure that path exists
+
+ if (!processPath || !existsSync(processPath)) {
+ throw new Error('Invalid process path');
+ }
+
+ args = [processPath].concat(startPath+args);
+
+ // This works for node based CLIs, but can easily be adjusted to
+ // any other process installed in the system
+ return spawn('node', args, {
+ // env: Object.assign(
+ // {
+ // // NODE_ENV: 'jest',
+ // preventAutoStart: false,
+ // PATH // This is needed in order to get all the binaries in your current terminal
+ // },
+ // env
+ // ),
+ stdio: [null, null, null, 'ipc'] // This enables interprocess communication (IPC)
+ });
+}
+
+/**
+ * Creates a command and executes inputs (user responses) to the stdin
+ * Returns a promise that resolves when all inputs are sent
+ * Rejects the promise if any error
+ * @param {string} processPath Path of the process to execute
+ * @param {Array} args Arguments to the command
+ * @param {Array} inputs (Optional) Array of inputs (user responses)
+ * @param {Object} opts (optional) Environment variables
+ */
+function executeWithInput(processPath, startPath, args = [], inputs = [], opts = {}) {
+ if (!Array.isArray(inputs)) {
+ opts = inputs;
+ inputs = [];
+ }
+
+ const { env = null, timeout = 100, maxTimeout = 60 * 60 * 1000 } = opts;
+
+ let scriptOutput = '';
+
+ const childProcess = createProcess(processPath, startPath, args, env);
+ childProcess.stdin.setEncoding('utf-8');
+
+ let currentInputTimeout, killIOTimeout;
+
+ // Creates a loop to feed user inputs to the child process in order to get results from the tool
+ // This code is heavily inspired (if not blantantly copied) from inquirer-test:
+ // https://github.com/ewnd9/inquirer-test/blob/6e2c40bbd39a061d3e52a8b1ee52cdac88f8d7f7/index.js#L14
+ const loop = inputs => {
+ if (killIOTimeout) {
+ clearTimeout(killIOTimeout);
+ }
+
+ if (!inputs.length) {
+ childProcess.stdin.end();
+
+ // Set a timeout to wait for CLI response. If CLI takes longer than
+ // maxTimeout to respond, kill the childProcess and notify user
+ killIOTimeout = setTimeout(() => {
+ console.error('Error: Reached I/O timeout');
+ childProcess.kill(constants.signals.SIGTERM);
+ }, maxTimeout);
+
+ return;
+ }
+
+ currentInputTimeout = setTimeout(() => {
+ childProcess.stdin.write(inputs[0]);
+ // Log debug I/O statements on tests
+ if (env && env.DEBUG) {
+ console.log('input:', inputs[0]);
+ }
+ loop(inputs.slice(1));
+ }, timeout);
+ };
+
+ const promise = new Promise((resolve, reject) => {
+ // Get errors from CLI
+ childProcess.stderr.on('data', data => {
+ // Log debug I/O statements on tests
+ if (env && env.DEBUG) {
+ console.log('error:', data.toString());
+ }
+ });
+
+ // Get output from CLI
+ childProcess.stdout.on('data', data => {
+
+ const str = data.toString();
+ scriptOutput += str;
+
+ // Log debug I/O statements on tests
+ if (env && env.DEBUG) {
+ console.log('output:', str);
+ }
+
+ if (str.startsWith('Done!') || str.startsWith('Test failed:')) {
+ if (process.platform === 'darwin') {
+ childProcess.kill();
+ resolve(scriptOutput);
+ }
+ }
+ });
+
+ childProcess.stderr.once('data', err => {
+ childProcess.stdin.end();
+
+ if (currentInputTimeout) {
+ clearTimeout(currentInputTimeout);
+ inputs = [];
+ }
+
+ const ignoreE = 'error: [Oxygen] Error initializing module "db": `unixodbc` binaries not installed';
+
+ const errMessage = err.toString();
+
+ if (errMessage.includes(ignoreE)) {
+ console.log('stderr', errMessage);
+ }
+ });
+
+ childProcess.on('error', reject);
+
+ // Kick off the process
+ loop(inputs);
+
+ childProcess.stdout.pipe(
+ concat(result => {
+ if (killIOTimeout) {
+ clearTimeout(killIOTimeout);
+ }
+
+ resolve(result.toString());
+ })
+ );
+ });
+
+ // Appending the process to the promise, in order to
+ // add additional parameters or behavior (such as IPC communication)
+ promise.attachedProcess = childProcess;
+
+ return promise;
+}
+
+module.exports = {
+ createProcess,
+ create: (processPath, startPath) => {
+ const fn = (...args) => executeWithInput(processPath, startPath, ...args);
+
+ return {
+ execute: fn
+ };
+ },
+ DOWN: '\x1B\x5B\x42',
+ UP: '\x1B\x5B\x41',
+ ENTER: '\x0D',
+ SPACE: '\x20'
+};
\ No newline at end of file
diff --git a/e2e/tools/config.js b/e2e/tools/config.js
new file mode 100644
index 00000000..55f9d18e
--- /dev/null
+++ b/e2e/tools/config.js
@@ -0,0 +1,15 @@
+const path = require('path');
+const config = require('./config.json');
+
+let start = config.start;
+
+if (process.platform === 'darwin') {
+ start = config.startDarwin;
+}
+
+start = path.resolve(__dirname, '../../'+start);
+
+module.exports = {
+ start: start,
+ afterStart: 'e2e/tests'
+};
\ No newline at end of file
diff --git a/e2e/tools/config.json b/e2e/tools/config.json
new file mode 100644
index 00000000..944c8423
--- /dev/null
+++ b/e2e/tools/config.json
@@ -0,0 +1,4 @@
+{
+ "start" : "\\build\\lib\\cli.js",
+ "startDarwin" : "/build/lib/cli.js"
+}
\ No newline at end of file
diff --git a/e2e/tools/resultHelper.js b/e2e/tools/resultHelper.js
new file mode 100644
index 00000000..b012aeae
--- /dev/null
+++ b/e2e/tools/resultHelper.js
@@ -0,0 +1,62 @@
+const expect = require('chai').expect;
+const passedRegex = /Test \d|\w has finished with status: PASSED/g;
+const failedRegex = /Test \d|\w has finished with status: FAILED/g;
+
+const passedTest = (text) => {
+ let result = false;
+
+ const matchResult = text.match(passedRegex);
+
+ if (matchResult) {
+ result = matchResult.join().endsWith('has finished with status: PASSED');
+ }
+
+ return result;
+};
+
+const failedTest = (text) => {
+ let result = false;
+
+ const matchResult = text.match(failedRegex);
+
+ if (matchResult) {
+ result = matchResult.join().endsWith('has finished with status: FAILED');
+ }
+
+ return result;
+};
+
+const shouldPass = (response) => {
+ const passed = passedTest(response);
+ const failed = failedTest(response);
+
+ if (!passed) {
+ console.log(response);
+ } else if (failed) {
+ console.log(response);
+ }
+
+ expect(passed).to.equal(true);
+ expect(failed).to.equal(false);
+};
+
+const shouldFail = (response) => {
+ const passed = passedTest(response);
+ const failed = failedTest(response);
+
+ if (passed) {
+ console.log(response);
+ } else if (!failed) {
+ console.log(response);
+ }
+
+ expect(passed).to.equal(false);
+ expect(failed).to.equal(true);
+};
+
+module.exports = {
+ passedTest,
+ failedTest,
+ shouldPass,
+ shouldFail
+};
\ No newline at end of file
diff --git a/package.json b/package.json
index 283aa70c..b3da9c38 100644
--- a/package.json
+++ b/package.json
@@ -38,11 +38,11 @@
"@babel/core": "7.10.5",
"@babel/preset-env": "7.10.4",
"babel-plugin-source-map-support": "2.1.3",
- "cross-env": "7.0.2",
"doctrine": "3.0.0",
"eslint": "6.8.0",
"husky": "4.2.5",
"md-reverse": "1.0.0",
+ "mocha": "^8.1.3",
"npm-run-all": "4.1.5"
},
"dependencies": {
@@ -105,7 +105,23 @@
"lint": "eslint \"src/**/*.js\" \"tools/**/*.js\"",
"apidoc": "node -r esm tools/apidoc",
"prod": "node ./build/lib/cli.js",
- "dev": "cross-env DEBUG=true NODE_ENV=development npm run compile && npm run prod"
+ "dev": "cross-env DEBUG=true NODE_ENV=development npm run compile && npm run prod",
+ "test-web": "mocha 'e2e/tests/web.js' --timeout 1000000",
+ "test-win": "mocha 'e2e/tests/win.js' --timeout 1000000",
+ "test-mob-web": "mocha 'e2e/tests/mob.web.js' --timeout 1000000",
+ "test-mob-android": "mocha 'e2e/tests/mob.android.js' --timeout 1000000",
+ "test-mob-ios": "mocha 'e2e/tests/mob.ios.js' --timeout 1000000",
+ "test-twilio": "mocha 'e2e/tests/twilio.js' --timeout 1000000",
+ "test-soap": "mocha 'e2e/tests/soap.js' --timeout 1000000",
+ "test-shell": "mocha 'e2e/tests/shell.js' --timeout 1000000",
+ "test-serial": "mocha 'e2e/tests/serial.js' --timeout 1000000",
+ "test-pdf": "mocha 'e2e/tests/pdf.js' --timeout 1000000",
+ "test-log": "mocha 'e2e/tests/log.js' --timeout 1000000",
+ "test-http": "mocha 'e2e/tests/http.js' --timeout 1000000",
+ "test-email": "mocha 'e2e/tests/email.js' --timeout 1000000",
+ "test-db": "mocha 'e2e/tests/db.js' --timeout 1000000",
+ "test-date": "mocha 'e2e/tests/date.js' --timeout 1000000",
+ "test-assert": "mocha 'e2e/tests/assert.js' --timeout 1000000"
},
"engines": {
"node": ">=10.18.1 <13.0"