Skip to content

Commit

Permalink
feat: add multiremote support (#272)
Browse files Browse the repository at this point in the history
* feat: add command asControl for multi remote to each browser

* feat: add support for multiremotedriver to call instances implicit

* feat: add support for ui5ready, navTo, make all tests running again

* feat: add missing browserinstance ref in browser js

* feat: move multiremote config to new location

* feat: add headless support for multiremote

* fix: remove DRY, due to prior merge conflict

* feat: #281 add missing browser instance references to cliend side js

* feat: set browser as default parameter for ui5 inject

* feat: change check for ui5 version on multiremote

* fix: linting issues

* chore: bump chromedriver to 103.0.0

* chore: set default screen size for testing cap to 1920x1280
  • Loading branch information
monavari-lebrecht authored Jun 24, 2022
1 parent 84e3624 commit fcb47cf
Show file tree
Hide file tree
Showing 25 changed files with 532 additions and 173 deletions.
4 changes: 2 additions & 2 deletions client-side-js/_checkForUI5Ready.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide__checkForUI5Ready() {
return await browser.executeAsync((done) => {
async function clientSide__checkForUI5Ready(browserInstance) {
return await browserInstance.executeAsync((done) => {
window.bridge
.waitForUI5(window.wdi5.waitForUI5Options)
.then(() => {
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/_getAggregation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
async function clientSide_getAggregation(webElement, aggregationName) {
async function clientSide_getAggregation(webElement, aggregationName, browserInstance) {
webElement = await Promise.resolve(webElement) // to plug into fluent async api
return await browser.executeAsync(
return await browserInstance.executeAsync(
(webElement, aggregationName, done) => {
window.bridge.waitForUI5(window.wdi5.waitForUI5Options).then(() => {
// DOM to UI5
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/_navTo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide__navTo(sComponentId, sName, oParameters, oComponentTargetInfo, bReplace) {
return await browser.executeAsync(
async function clientSide__navTo(sComponentId, sName, oParameters, oComponentTargetInfo, bReplace, browserInstance) {
return await browserInstance.executeAsync(
(sComponentId, sName, oParameters, oComponentTargetInfo, bReplace, done) => {
window.bridge.waitForUI5(window.wdi5.waitForUI5Options).then(() => {
window.wdi5.Log.info(`[browser wdi5] navigation to ${sName} triggered`)
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/allControls.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
async function clientSide_allControls(controlSelector) {
async function clientSide_allControls(controlSelector, browserInstance) {
controlSelector = await Promise.resolve(controlSelector) // to plug into fluent async api
return await browser.executeAsync((controlSelector, done) => {
return await browserInstance.executeAsync((controlSelector, done) => {
const waitForUI5Options = Object.assign({}, window.wdi5.waitForUI5Options)
if (controlSelector.timeout) {
waitForUI5Options.timeout = controlSelector.timeout
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/executeControlMethod.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide_executeControlMethod(webElement, methodName, args) {
return await browser.executeAsync(
async function clientSide_executeControlMethod(webElement, methodName, browserInstance, args) {
return await browserInstance.executeAsync(
(webElement, methodName, args, done) => {
window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/fireEvent.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide_fireEvent(webElement, eventName, oOptions) {
return await browser.executeAsync(
async function clientSide_fireEvent(webElement, eventName, oOptions, browserInstance) {
return await browserInstance.executeAsync(
(webElement, eventName, oOptions, done) => {
window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/getControl.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
async function clientSide_getControl(controlSelector) {
async function clientSide_getControl(controlSelector, browserInstance) {
controlSelector = await Promise.resolve(controlSelector) // to plug into fluent async api
return await browser.executeAsync((controlSelector, done) => {
return await browserInstance.executeAsync((controlSelector, done) => {
const waitForUI5Options = Object.assign({}, window.wdi5.waitForUI5Options)
if (controlSelector.timeout) {
waitForUI5Options.timeout = controlSelector.timeout
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/getSelectorForElement.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide_getSelectorForElement(oOptions) {
return await browser.executeAsync((oOptions, done) => {
async function clientSide_getSelectorForElement(oOptions, browserInstance) {
return await browserInstance.executeAsync((oOptions, done) => {
window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
() => {
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/getUI5Version.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* @returns {string} UI5 version number in string form
*/
async function clientSide_getUI5Version() {
return await browser.executeAsync((done) => {
async function clientSide_getUI5Version(browserInstance = browser) {
return await browserInstance.executeAsync((done) => {
done(sap.ui.version)
})
}
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/injectTools.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions client-side-js/injectUI5.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide_injectUI5(config, waitForUI5Timeout) {
return await browser.executeAsync((waitForUI5Timeout, done) => {
async function clientSide_injectUI5(config, waitForUI5Timeout, browserInstance) {
return await browserInstance.executeAsync((waitForUI5Timeout, done) => {
if (window.bridge) {
// setup sap testing already done
done(true)
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/interactWithControl.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function clientSide_interactWithControl(oOptions) {
return await browser.executeAsync((oOptions, done) => {
async function clientSide_interactWithControl(oOptions, browserInstance) {
return await browserInstance.executeAsync((oOptions, done) => {
window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
() => {
Expand Down
16 changes: 8 additions & 8 deletions client-side-js/testLibrary.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
async function initOPA(pageObjectConfig) {
return await browser.executeAsync((pageObjectConfig, done) => {
async function initOPA(pageObjectConfig, browserInstance) {
return await browserInstance.executeAsync((pageObjectConfig, done) => {
window.bridge
.waitForUI5(window.wdi5.waitForUI5Options)
.then(() => {
Expand Down Expand Up @@ -29,8 +29,8 @@ async function initOPA(pageObjectConfig) {
})
}, pageObjectConfig)
}
async function emptyQueue() {
return await browser.executeAsync((done) => {
async function emptyQueue(browserInstance) {
return await browserInstance.executeAsync((done) => {
window.bridge
.waitForUI5(window.wdi5.waitForUI5Options)
.then(() => {
Expand All @@ -47,8 +47,8 @@ async function emptyQueue() {
})
}

async function addToQueue(type, target, aMethods) {
return await browser.executeAsync(
async function addToQueue(type, target, aMethods, browserInstance) {
return await browserInstance.executeAsync(
(type, target, aMethods, done) => {
window.bridge
.waitForUI5(window.wdi5.waitForUI5Options)
Expand Down Expand Up @@ -88,8 +88,8 @@ async function addToQueue(type, target, aMethods) {
)
}

async function loadFELibraries() {
return await browser.executeAsync((done) => {
async function loadFELibraries(browserInstance = browser) {
return await browserInstance.executeAsync((done) => {
sap.ui.require(
["sap/fe/test/ListReport", "sap/fe/test/ObjectPage", "sap/fe/test/Shell"],
(ListReport, ObjectPage, Shell) => {
Expand Down
47 changes: 47 additions & 0 deletions examples/ui5-js-app/e2e-test-config/wdio-multiremote.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const { baseConfig } = require("./wdio.base.conf")
const { join } = require("path")
const merge = require("deepmerge")

// avoid multiple chrome sessions
delete baseConfig.capabilities

const _config = {
wdi5: {
url: "#",
screenshotPath: join("report", "screenshots")
},
maxInstances: 1,
capabilities: {
one: {
capabilities: {
browserName: "chrome",
acceptInsecureCerts: true,
"goog:chromeOptions": {
args:
process.argv.indexOf("--headless") > -1
? ["window-size=1440,800", "--headless"]
: process.argv.indexOf("--debug") > -1
? ["window-size=1920,1280", "--auto-open-devtools-for-tabs"]
: ["window-size=1440,800"]
}
}
},
two: {
capabilities: {
browserName: "chrome",
acceptInsecureCerts: true,
"goog:chromeOptions": {
args:
process.argv.indexOf("--headless") > -1
? ["window-size=1440,800", "--headless"]
: process.argv.indexOf("--debug") > -1
? ["window-size=1920,1280", "--auto-open-devtools-for-tabs"]
: ["window-size=1440,800"]
}
}
}
},
specs: ["webapp/test/e2e/multiremote.test.js"]
}

exports.config = merge(baseConfig, _config)
2 changes: 1 addition & 1 deletion examples/ui5-js-app/e2e-test-config/wdio-webserver.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const _config = {
url: "#"
},
specs: [join("webapp", "test", "e2e", "**/*.test.js")],
exclude: [join("webapp", "test", "e2e", "ui5-late.test.js")],
exclude: [join("webapp", "test", "e2e", "ui5-late.test.js"), join("webapp", "test", "e2e", "multiremote.test.js")],
baseUrl: "http://localhost:8888"
}

Expand Down
4 changes: 2 additions & 2 deletions examples/ui5-js-app/e2e-test-config/wdio.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ exports.baseConfig = {
"goog:chromeOptions": {
args:
process.argv.indexOf("--headless") > -1
? ["window-size=1440,800", "--headless"]
? ["window-size=1920,1280", "--headless"]
: process.argv.indexOf("--debug") > -1
? ["window-size=1920,1280", "--auto-open-devtools-for-tabs"]
: ["window-size=1440,800"]
: ["window-size=1920,1280"]
}
}
],
Expand Down
3 changes: 2 additions & 1 deletion examples/ui5-js-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"test:lateInject": "wdio run e2e-test-config/wdio-ui5-late.conf.js",
"test:ui5tooling": "wdio run e2e-test-config/wdio-ui5tooling.conf.js",
"test:webserver": "wdio run e2e-test-config/wdio-webserver.conf.js",
"test:multiremote": "wdio run e2e-test-config/wdio-multiremote.conf.js",
"test:multiversion": "node e2e-test-config/wdi5-multiversion.js",
"test-selenium": "wdio run e2e-test-config/wdio-selenium-service.conf.js"
},
Expand All @@ -24,7 +25,7 @@
"@wdio/mocha-framework": "^7.19.7",
"@wdio/selenium-standalone-service": "^7.19.5",
"@wdio/spec-reporter": "^7.19.7",
"chromedriver": "^101.0.0",
"chromedriver": "^103.0.0",
"ui5-middleware-simpleproxy": "^0.8.4",
"wdio-chromedriver-service": "^7.3.2",
"wdio-ui5-service": "*"
Expand Down
47 changes: 47 additions & 0 deletions examples/ui5-js-app/webapp/test/e2e/multiremote.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const Main = require("./pageObjects/Main")
describe("Multi Remote", () => {
before(async () => {
await Main.open()
})

it("allows handling ui5 controls in different browsers", async () => {
const button = await browser.two.asControl({
selector: {
id: "openDialogButton",
viewName: "test.Sample.view.Main"
}
})
const metadata = button.getControlInfo()

expect(metadata.id).toEqual("container-Sample---Main--openDialogButton")
expect(metadata.className).toEqual("sap.m.Button")
expect(metadata.key).toEqual("openDialogButtontestSample.view.Main")

await button.press()

const dialogSelector = {
selector: {
id: "Dialog-title",
searchOpenDialogs: true
}
}

const text = await browser.two.asControl(dialogSelector).getText()
expect(text).toEqual("Here we are!")
expect(await browser.one.asControl(dialogSelector).getInitStatus()).toBeFalsy()
})
it("should return an array of results of both browsers if called directly by browser", async () => {
const button = await browser.asControl({
selector: {
id: "openDialogButton",
viewName: "test.Sample.view.Main"
}
})
const buttonOne = button[0]
const buttonTwo = button[1]
expect(buttonOne._browserInstance.sessionId).not.toEqual(buttonTwo._browserInstance.sessionId)

expect(await buttonOne.getText()).toEqual("open Dialog")
expect(await buttonTwo.getText()).toEqual("open Dialog")
})
})
Loading

0 comments on commit fcb47cf

Please sign in to comment.