From 9af5c767e0d4851f8e69b8a290025f2818aee5a1 Mon Sep 17 00:00:00 2001 From: scoen Date: Wed, 2 Nov 2022 10:01:47 +0100 Subject: [PATCH 01/35] feat: btp authenticator - introduce authenticator .conf file - introduce authenticator test scripts - add first dummy btp authenticator login script - add dotenv to load .env variables - authenticate when wdi5_authenticate is in capabilities --- .../wdio-btp-authentication.conf.js | 32 +++++++++++++++++++ examples/ui5-js-app/package.json | 6 ++-- package-lock.json | 9 +++--- package.json | 1 + src/index.ts | 2 ++ src/lib/authentication/Authenticator.ts | 1 + src/lib/authentication/BTPAuthenticator.ts | 15 +++++++++ src/lib/wdi5-bridge.ts | 11 +++++++ src/service.ts | 5 ++- 9 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js create mode 100644 src/lib/authentication/Authenticator.ts create mode 100644 src/lib/authentication/BTPAuthenticator.ts diff --git a/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js b/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js new file mode 100644 index 00000000..1a48c1d5 --- /dev/null +++ b/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js @@ -0,0 +1,32 @@ +const { join } = require("path") +const { baseConfig } = require("../wdio.base.conf") +const merge = require("deepmerge") + +const _config = { + wdi5: { + url: "#" + }, + specs: [join("webapp", "test", "e2e", "**/basic.test.js")], + baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/xsuaa/" +} +// we need to overwrite and not merge it +baseConfig.capabilities = [ + { + "wdi5:authentication": { + provider: "BTP" + }, + maxInstances: 4, + browserName: "chrome", + acceptInsecureCerts: true, + "goog:chromeOptions": { + args: + process.argv.indexOf("--headless") > -1 + ? ["window-size=1920,1280", "--headless"] + : process.argv.indexOf("--debug") > -1 + ? ["window-size=1920,1280", "--auto-open-devtools-for-tabs"] + : ["window-size=1920,1280"] + } + } +] + +exports.config = merge(baseConfig, _config) diff --git a/examples/ui5-js-app/package.json b/examples/ui5-js-app/package.json index be5f9301..9cfbd966 100644 --- a/examples/ui5-js-app/package.json +++ b/examples/ui5-js-app/package.json @@ -8,7 +8,7 @@ "main": "webapp/index.html", "scripts": { "serve": "ui5 serve", - "test": "run-s test:*", + "test": "run-s test:authentication", "test-h": "run-s \"test:* -- --headless\"", "start": "soerver -d ./webapp -p 8888 -x ./webapp/proxyrc.json", "test:lateInject": "wdio run e2e-test-config/wdio-ui5-late.conf.js", @@ -16,7 +16,9 @@ "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" + "test-selenium": "wdio run e2e-test-config/wdio-selenium-service.conf.js", + "test:authentication": "run-s authentication:btp", + "authentication:btp": "wdio run e2e-test-config/authentication/wdio-btp-authentication.conf.js" }, "devDependencies": { "@ui5/cli": "^2.14.10", diff --git a/package-lock.json b/package-lock.json index e557678e..d4805ca2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "examples/ui5-ts-app" ], "dependencies": { + "dotenv": "^16.0.3", "semver": "^7.3.7" }, "devDependencies": { @@ -11195,7 +11196,6 @@ "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "dev": true, "engines": { "node": ">=12" } @@ -29440,8 +29440,7 @@ "dotenv": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "dev": true + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "dotgitignore": { "version": "2.1.0", @@ -35663,6 +35662,7 @@ "chromedriver": "latest", "cross-env": "^7.0.3", "deepmerge": "^4.2.2", + "dotenv": "^16.0.3", "eslint": "^8.23.1", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", @@ -45365,8 +45365,7 @@ "dotenv": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", - "dev": true + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "dotgitignore": { "version": "2.1.0", diff --git a/package.json b/package.json index a7c098a2..175611af 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "*.ts": "eslint --cache --fix" }, "dependencies": { + "dotenv": "^16.0.3", "semver": "^7.3.7" }, "devDependencies": { diff --git a/src/index.ts b/src/index.ts index f555d482..82c86ee6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ import Launcher from "./launcher" import Service from "./service" import { wdi5 as _wdi5 } from "./wdi5" +import * as dotenv from "dotenv" +dotenv.config() export default Service export const launcher = Launcher diff --git a/src/lib/authentication/Authenticator.ts b/src/lib/authentication/Authenticator.ts new file mode 100644 index 00000000..a063a9bb --- /dev/null +++ b/src/lib/authentication/Authenticator.ts @@ -0,0 +1 @@ +export default class Authenticator {} diff --git a/src/lib/authentication/BTPAuthenticator.ts b/src/lib/authentication/BTPAuthenticator.ts new file mode 100644 index 00000000..966248f8 --- /dev/null +++ b/src/lib/authentication/BTPAuthenticator.ts @@ -0,0 +1,15 @@ +import Authenticator from "./Authenticator" +class BTPAuthenticator extends Authenticator { + async login() { + const username = await $("#j_username") + const submit = await $("#logOnFormSubmit") + + await username.setValue(process.env.wdi5_username) + await submit.click() + const password = await $("#j_password") + await password.setValue(process.env.wdi5_password) + await submit.click() + } +} + +export default new BTPAuthenticator() diff --git a/src/lib/wdi5-bridge.ts b/src/lib/wdi5-bridge.ts index c903eb65..592d85df 100644 --- a/src/lib/wdi5-bridge.ts +++ b/src/lib/wdi5-bridge.ts @@ -16,6 +16,7 @@ import { clientSide_getUI5Version } from "../../client-side-js/getUI5Version" import { clientSide__navTo } from "../../client-side-js/_navTo" import { clientSide_allControls } from "../../client-side-js/allControls" import { Logger as _Logger } from "./Logger" +import BTPAuthenticator from "./authentication/BTPAuthenticator" const Logger = _Logger.getInstance() @@ -138,6 +139,16 @@ export async function checkForUI5Page() { }) } +export async function authenticate(options) { + switch (options.provider) { + case "BTP": + await BTPAuthenticator.login() + break + default: + break + } +} + //****************************************************************************************** // private diff --git a/src/service.ts b/src/service.ts index 5c27d326..0011837d 100644 --- a/src/service.ts +++ b/src/service.ts @@ -1,7 +1,7 @@ import { Capabilities, Services } from "@wdio/types" import { MultiRemoteDriver } from "webdriverio/build/multiremote" -import { start, injectUI5, setup, checkForUI5Page } from "./lib/wdi5-bridge" +import { start, injectUI5, setup, checkForUI5Page, authenticate } from "./lib/wdi5-bridge" import { wdi5Config } from "./types/wdi5.types" import { Logger as _Logger } from "./lib/Logger" @@ -25,6 +25,9 @@ export default class Service implements Services.ServiceInstance { await injectUI5(this._config as wdi5Config, browser[name]) } } else { + if (this._capabilities["wdi5:authenticate"]) { + await authenticate(this._capabilities["wdi5:authentication"]) + } await injectUI5(this._config as wdi5Config, browser) } } else { From 916225b6390a98004a4641e6df054cccbbb5c7f9 Mon Sep 17 00:00:00 2001 From: scoen Date: Thu, 3 Nov 2022 17:22:46 +0100 Subject: [PATCH 02/35] feat: btp and basicauth authenticator - move authenticator tests to the ts-app - add BasicAuth support and tests - enhance BTP login --- .../wdio-btp-authentication.conf.js | 32 ------------ examples/ui5-js-app/package.json | 6 +-- examples/ui5-ts-app/package.json | 6 ++- .../wdio-basic-auth-authentication.conf.ts | 50 +++++++++++++++++++ .../wdio-btp-authentication.conf.ts | 50 +++++++++++++++++++ src/lib/authentication/BTPAuthenticator.ts | 17 +++++-- src/lib/authentication/BasicAuthenticator.ts | 16 ++++++ src/lib/wdi5-bridge.ts | 3 ++ src/service.ts | 3 +- 9 files changed, 140 insertions(+), 43 deletions(-) delete mode 100644 examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js create mode 100644 examples/ui5-ts-app/test/e2e/authentication/wdio-basic-auth-authentication.conf.ts create mode 100644 examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication.conf.ts create mode 100644 src/lib/authentication/BasicAuthenticator.ts diff --git a/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js b/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js deleted file mode 100644 index 1a48c1d5..00000000 --- a/examples/ui5-js-app/e2e-test-config/authentication/wdio-btp-authentication.conf.js +++ /dev/null @@ -1,32 +0,0 @@ -const { join } = require("path") -const { baseConfig } = require("../wdio.base.conf") -const merge = require("deepmerge") - -const _config = { - wdi5: { - url: "#" - }, - specs: [join("webapp", "test", "e2e", "**/basic.test.js")], - baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/xsuaa/" -} -// we need to overwrite and not merge it -baseConfig.capabilities = [ - { - "wdi5:authentication": { - provider: "BTP" - }, - maxInstances: 4, - browserName: "chrome", - acceptInsecureCerts: true, - "goog:chromeOptions": { - args: - process.argv.indexOf("--headless") > -1 - ? ["window-size=1920,1280", "--headless"] - : process.argv.indexOf("--debug") > -1 - ? ["window-size=1920,1280", "--auto-open-devtools-for-tabs"] - : ["window-size=1920,1280"] - } - } -] - -exports.config = merge(baseConfig, _config) diff --git a/examples/ui5-js-app/package.json b/examples/ui5-js-app/package.json index 9cfbd966..be5f9301 100644 --- a/examples/ui5-js-app/package.json +++ b/examples/ui5-js-app/package.json @@ -8,7 +8,7 @@ "main": "webapp/index.html", "scripts": { "serve": "ui5 serve", - "test": "run-s test:authentication", + "test": "run-s test:*", "test-h": "run-s \"test:* -- --headless\"", "start": "soerver -d ./webapp -p 8888 -x ./webapp/proxyrc.json", "test:lateInject": "wdio run e2e-test-config/wdio-ui5-late.conf.js", @@ -16,9 +16,7 @@ "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", - "test:authentication": "run-s authentication:btp", - "authentication:btp": "wdio run e2e-test-config/authentication/wdio-btp-authentication.conf.js" + "test-selenium": "wdio run e2e-test-config/wdio-selenium-service.conf.js" }, "devDependencies": { "@ui5/cli": "^2.14.10", diff --git a/examples/ui5-ts-app/package.json b/examples/ui5-ts-app/package.json index 477f3604..871aac16 100644 --- a/examples/ui5-ts-app/package.json +++ b/examples/ui5-ts-app/package.json @@ -8,7 +8,11 @@ "start": "npm-run-all --parallel watch:ts start:ui5", "watch:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files --watch", "start:ui5": "ui5 serve --port 8080", - "test": "wdio run wdio-ui5.conf.ts", + "test": "run-s test:*", + "test:basic": "wdio run wdio-ui5.conf.ts", + "test:authentication": "run-s authentication:*", + "authentication:btp": "wdio run test/e2e/authentication/wdio-btp-authentication.conf.ts", + "authentication:basic-auth": "wdio run test/e2e/authentication/wdio-basic-auth-authentication.conf.ts", "build:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files", "build:ui5": "ui5 build --clean-dest", "build:mtar": "mv dist approuter/webapp && mbt build", diff --git a/examples/ui5-ts-app/test/e2e/authentication/wdio-basic-auth-authentication.conf.ts b/examples/ui5-ts-app/test/e2e/authentication/wdio-basic-auth-authentication.conf.ts new file mode 100644 index 00000000..23e363ba --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/authentication/wdio-basic-auth-authentication.conf.ts @@ -0,0 +1,50 @@ +import { join } from "path" +import { wdi5Config } from "wdio-ui5-service/dist/types/wdi5.types" + +export const config: wdi5Config = { + wdi5: { + screenshotPath: join("test", "__screenshots__"), + url: "#", + waitForUI5Timeout: 30000 + }, + baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/basic-auth/", + + services: ["chromedriver", "ui5"], + + specs: ["./test/e2e/**/*.test.ts"], + + maxInstances: 10, + capabilities: [ + { + //@ts-ignore + "wdi5:authentication": { + provider: "BasicAuth" + }, + maxInstances: 5, + browserName: "chrome", + "goog:chromeOptions": { + args: + process.argv.indexOf("--headless") > -1 + ? ["--headless"] + : process.argv.indexOf("--debug") > -1 + ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] + : ["window-size=1440,800"] + }, + acceptInsecureCerts: true + } + ], + logLevel: "error", + bail: 0, + + waitforTimeout: 10000, + connectionRetryTimeout: process.argv.indexOf("--debug") > -1 ? 1200000 : 120000, + connectionRetryCount: 3, + + reporters: ["spec"], + + framework: "mocha", + mochaOpts: { + ui: "bdd", + timeout: process.argv.indexOf("--debug") > -1 ? 600000 : 60000 + } +} diff --git a/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication.conf.ts b/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication.conf.ts new file mode 100644 index 00000000..0a606c0f --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication.conf.ts @@ -0,0 +1,50 @@ +import { join } from "path" +import { wdi5Config } from "wdio-ui5-service/dist/types/wdi5.types" + +export const config: wdi5Config = { + wdi5: { + screenshotPath: join("test", "__screenshots__"), + url: "", + waitForUI5Timeout: 30000 + }, + baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/xsuaa/", + + services: ["chromedriver", "ui5"], + + specs: ["./test/e2e/**/*.test.ts"], + + maxInstances: 10, + capabilities: [ + { + //@ts-ignore + "wdi5:authentication": { + provider: "BTP" + }, + maxInstances: 5, + browserName: "chrome", + "goog:chromeOptions": { + args: + process.argv.indexOf("--headless") > -1 + ? ["--headless"] + : process.argv.indexOf("--debug") > -1 + ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] + : ["window-size=1440,800"] + }, + acceptInsecureCerts: true + } + ], + logLevel: "error", + bail: 0, + + waitforTimeout: 10000, + connectionRetryTimeout: process.argv.indexOf("--debug") > -1 ? 1200000 : 120000, + connectionRetryCount: 3, + + reporters: ["spec"], + + framework: "mocha", + mochaOpts: { + ui: "bdd", + timeout: process.argv.indexOf("--debug") > -1 ? 600000 : 60000 + } +} diff --git a/src/lib/authentication/BTPAuthenticator.ts b/src/lib/authentication/BTPAuthenticator.ts index 966248f8..63fd516e 100644 --- a/src/lib/authentication/BTPAuthenticator.ts +++ b/src/lib/authentication/BTPAuthenticator.ts @@ -3,12 +3,19 @@ class BTPAuthenticator extends Authenticator { async login() { const username = await $("#j_username") const submit = await $("#logOnFormSubmit") - - await username.setValue(process.env.wdi5_username) - await submit.click() const password = await $("#j_password") - await password.setValue(process.env.wdi5_password) - await submit.click() + + if (await password.isExisting()) { + await username.setValue(process.env.wdi5_username) + await password.setValue(process.env.wdi5_password) + await submit.click() + } else { + await username.setValue(process.env.wdi5_username) + await submit.click() + const password = await $("#j_password") + await password.setValue(process.env.wdi5_password) + await submit.click() + } } } diff --git a/src/lib/authentication/BasicAuthenticator.ts b/src/lib/authentication/BasicAuthenticator.ts new file mode 100644 index 00000000..650d7fe5 --- /dev/null +++ b/src/lib/authentication/BasicAuthenticator.ts @@ -0,0 +1,16 @@ +import Authenticator from "./Authenticator" +class BasicAuthenticator extends Authenticator { + async login() { + const url = await browser.getUrl() + const matches = await url.match(/(\w*:?\/\/)(.+)/) + + const basicAuthUrl = matches[1] + process.env.wdi5_username + ":" + process.env.wdi5_password + "@" + matches[2] + + await browser.url(basicAuthUrl) + + // trick 17 + await browser.url(url) + } +} + +export default new BasicAuthenticator() diff --git a/src/lib/wdi5-bridge.ts b/src/lib/wdi5-bridge.ts index 592d85df..7f306cec 100644 --- a/src/lib/wdi5-bridge.ts +++ b/src/lib/wdi5-bridge.ts @@ -17,6 +17,7 @@ import { clientSide__navTo } from "../../client-side-js/_navTo" import { clientSide_allControls } from "../../client-side-js/allControls" import { Logger as _Logger } from "./Logger" import BTPAuthenticator from "./authentication/BTPAuthenticator" +import BasicAuthenticator from "./authentication/BasicAuthenticator" const Logger = _Logger.getInstance() @@ -144,6 +145,8 @@ export async function authenticate(options) { case "BTP": await BTPAuthenticator.login() break + case "BasicAuth": + await BasicAuthenticator.login() default: break } diff --git a/src/service.ts b/src/service.ts index 0011837d..313d5313 100644 --- a/src/service.ts +++ b/src/service.ts @@ -25,9 +25,10 @@ export default class Service implements Services.ServiceInstance { await injectUI5(this._config as wdi5Config, browser[name]) } } else { - if (this._capabilities["wdi5:authenticate"]) { + if (this._capabilities["wdi5:authentication"]) { await authenticate(this._capabilities["wdi5:authentication"]) } + await checkForUI5Page() await injectUI5(this._config as wdi5Config, browser) } } else { From c5c3602ffddf6b6016a85db6fd8a3769608b6809 Mon Sep 17 00:00:00 2001 From: scoen Date: Fri, 4 Nov 2022 12:37:52 +0100 Subject: [PATCH 03/35] feat: add custom authenticator --- examples/ui5-ts-app/package.json | 3 +- .../wdio-custom-authentication.conf.ts | 53 +++++++++++++++++++ src/lib/authentication/CustomAuthenticator.ts | 14 +++++ src/lib/wdi5-bridge.ts | 4 ++ src/service.ts | 1 - 5 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 examples/ui5-ts-app/test/e2e/authentication/wdio-custom-authentication.conf.ts create mode 100644 src/lib/authentication/CustomAuthenticator.ts diff --git a/examples/ui5-ts-app/package.json b/examples/ui5-ts-app/package.json index 871aac16..52f1be6d 100644 --- a/examples/ui5-ts-app/package.json +++ b/examples/ui5-ts-app/package.json @@ -8,11 +8,12 @@ "start": "npm-run-all --parallel watch:ts start:ui5", "watch:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files --watch", "start:ui5": "ui5 serve --port 8080", - "test": "run-s test:*", + "test": "run-s test:authentication", "test:basic": "wdio run wdio-ui5.conf.ts", "test:authentication": "run-s authentication:*", "authentication:btp": "wdio run test/e2e/authentication/wdio-btp-authentication.conf.ts", "authentication:basic-auth": "wdio run test/e2e/authentication/wdio-basic-auth-authentication.conf.ts", + "authentication:custom": "wdio run test/e2e/authentication/wdio-custom-authentication.conf.ts", "build:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files", "build:ui5": "ui5 build --clean-dest", "build:mtar": "mv dist approuter/webapp && mbt build", diff --git a/examples/ui5-ts-app/test/e2e/authentication/wdio-custom-authentication.conf.ts b/examples/ui5-ts-app/test/e2e/authentication/wdio-custom-authentication.conf.ts new file mode 100644 index 00000000..6f2bf297 --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/authentication/wdio-custom-authentication.conf.ts @@ -0,0 +1,53 @@ +import { join } from "path" +import { wdi5Config } from "wdio-ui5-service/dist/types/wdi5.types" + +export const config: wdi5Config = { + wdi5: { + screenshotPath: join("test", "__screenshots__"), + url: "", + waitForUI5Timeout: 30000 + }, + baseUrl: "https://the-internet.herokuapp.com/login", + + services: ["chromedriver", "ui5"], + + // specs: ["./test/e2e/**/basic.test.ts"], + + maxInstances: 10, + capabilities: [ + { + //@ts-ignore + "wdi5:authentication": { + provider: "custom", + usernameSelector: "input[id='username']", + passwordSelector: "input[id='password']", + submitSelector: "button[type='submit']" + }, + maxInstances: 5, + browserName: "chrome", + "goog:chromeOptions": { + args: + process.argv.indexOf("--headless") > -1 + ? ["--headless"] + : process.argv.indexOf("--debug") > -1 + ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] + : ["window-size=1440,800"] + }, + acceptInsecureCerts: true + } + ], + logLevel: "error", + bail: 0, + + waitforTimeout: 10000, + connectionRetryTimeout: process.argv.indexOf("--debug") > -1 ? 1200000 : 120000, + connectionRetryCount: 3, + + reporters: ["spec"], + + framework: "mocha", + mochaOpts: { + ui: "bdd", + timeout: process.argv.indexOf("--debug") > -1 ? 600000 : 60000 + } +} diff --git a/src/lib/authentication/CustomAuthenticator.ts b/src/lib/authentication/CustomAuthenticator.ts new file mode 100644 index 00000000..a060ad1c --- /dev/null +++ b/src/lib/authentication/CustomAuthenticator.ts @@ -0,0 +1,14 @@ +import Authenticator from "./Authenticator" +class CustomAuthenticator extends Authenticator { + async login(options) { + const username = await $(options.usernameSelector) + const submit = await $(options.submitSelector) + const password = await $(options.passwordSelector) + + await username.setValue(process.env.wdi5_username) + await password.setValue(process.env.wdi5_password) + await submit.click() + } +} + +export default new CustomAuthenticator() diff --git a/src/lib/wdi5-bridge.ts b/src/lib/wdi5-bridge.ts index 7f306cec..2cd4b428 100644 --- a/src/lib/wdi5-bridge.ts +++ b/src/lib/wdi5-bridge.ts @@ -18,6 +18,7 @@ import { clientSide_allControls } from "../../client-side-js/allControls" import { Logger as _Logger } from "./Logger" import BTPAuthenticator from "./authentication/BTPAuthenticator" import BasicAuthenticator from "./authentication/BasicAuthenticator" +import CustomAuthenticator from "./authentication/CustomAuthenticator" const Logger = _Logger.getInstance() @@ -147,6 +148,9 @@ export async function authenticate(options) { break case "BasicAuth": await BasicAuthenticator.login() + break + case "custom": + await CustomAuthenticator.login(options) default: break } diff --git a/src/service.ts b/src/service.ts index 313d5313..3e3db122 100644 --- a/src/service.ts +++ b/src/service.ts @@ -28,7 +28,6 @@ export default class Service implements Services.ServiceInstance { if (this._capabilities["wdi5:authentication"]) { await authenticate(this._capabilities["wdi5:authentication"]) } - await checkForUI5Page() await injectUI5(this._config as wdi5Config, browser) } } else { From 0814756ac76de2e8d966928e43b4b36e10f1637c Mon Sep 17 00:00:00 2001 From: scoen Date: Mon, 7 Nov 2022 23:34:10 +0100 Subject: [PATCH 04/35] feat: authenticator allow overwriting of the default selectors --- src/lib/authentication/Authenticator.ts | 6 +++++- src/lib/authentication/BTPAuthenticator.ts | 17 ++++++++++++----- src/lib/authentication/CustomAuthenticator.ts | 17 ++++++++++++----- src/lib/wdi5-bridge.ts | 4 ++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/lib/authentication/Authenticator.ts b/src/lib/authentication/Authenticator.ts index a063a9bb..5e0dba3d 100644 --- a/src/lib/authentication/Authenticator.ts +++ b/src/lib/authentication/Authenticator.ts @@ -1 +1,5 @@ -export default class Authenticator {} +export default class Authenticator { + usernameSelector: string + passwordSelector: string + submitSelector: string +} diff --git a/src/lib/authentication/BTPAuthenticator.ts b/src/lib/authentication/BTPAuthenticator.ts index 63fd516e..c7795e9e 100644 --- a/src/lib/authentication/BTPAuthenticator.ts +++ b/src/lib/authentication/BTPAuthenticator.ts @@ -1,9 +1,16 @@ import Authenticator from "./Authenticator" class BTPAuthenticator extends Authenticator { + constructor(options) { + super() + this.usernameSelector = options.usernameSelector ?? "#j_username" + this.passwordSelector = options.passwordSelector ?? "#j_password" + this.submitSelector = options.submitSelector ?? "#logOnFormSubmit" + } + async login() { - const username = await $("#j_username") - const submit = await $("#logOnFormSubmit") - const password = await $("#j_password") + const username = await $(this.usernameSelector) + const submit = await $(this.submitSelector) + const password = await $(this.passwordSelector) if (await password.isExisting()) { await username.setValue(process.env.wdi5_username) @@ -12,11 +19,11 @@ class BTPAuthenticator extends Authenticator { } else { await username.setValue(process.env.wdi5_username) await submit.click() - const password = await $("#j_password") + const password = await $(this.passwordSelector) await password.setValue(process.env.wdi5_password) await submit.click() } } } -export default new BTPAuthenticator() +export default BTPAuthenticator diff --git a/src/lib/authentication/CustomAuthenticator.ts b/src/lib/authentication/CustomAuthenticator.ts index a060ad1c..8091e405 100644 --- a/src/lib/authentication/CustomAuthenticator.ts +++ b/src/lib/authentication/CustomAuthenticator.ts @@ -1,9 +1,16 @@ import Authenticator from "./Authenticator" class CustomAuthenticator extends Authenticator { - async login(options) { - const username = await $(options.usernameSelector) - const submit = await $(options.submitSelector) - const password = await $(options.passwordSelector) + constructor(options) { + super() + this.usernameSelector = options.usernameSelector ?? "Logger.error()" + this.passwordSelector = options.passwordSelector ?? "Logger.error()" + this.submitSelector = options.submitSelector ?? "Logger.error" + } + + async login() { + const username = await $(this.usernameSelector) + const submit = await $(this.submitSelector) + const password = await $(this.passwordSelector) await username.setValue(process.env.wdi5_username) await password.setValue(process.env.wdi5_password) @@ -11,4 +18,4 @@ class CustomAuthenticator extends Authenticator { } } -export default new CustomAuthenticator() +export default CustomAuthenticator diff --git a/src/lib/wdi5-bridge.ts b/src/lib/wdi5-bridge.ts index 2cd4b428..4bb73c88 100644 --- a/src/lib/wdi5-bridge.ts +++ b/src/lib/wdi5-bridge.ts @@ -144,13 +144,13 @@ export async function checkForUI5Page() { export async function authenticate(options) { switch (options.provider) { case "BTP": - await BTPAuthenticator.login() + await new BTPAuthenticator(options).login() break case "BasicAuth": await BasicAuthenticator.login() break case "custom": - await CustomAuthenticator.login(options) + await new CustomAuthenticator(options).login() default: break } From a9aaa6cd4c38095387a2ccd5f4bfd9bd120cf3c2 Mon Sep 17 00:00:00 2001 From: "dominik.feininger" Date: Thu, 10 Nov 2022 17:46:34 +0100 Subject: [PATCH 05/35] chore(pipeline): update set script for npm v9 --- .github/workflows/wdi5-tests_core.yml | 2 +- .github/workflows/wdi5-tests_fe-app.yml | 2 +- .github/workflows/wdi5-tests_js-app.yml | 2 +- .github/workflows/wdi5-tests_ts-app.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/wdi5-tests_core.yml b/.github/workflows/wdi5-tests_core.yml index 2561b75b..117f366e 100644 --- a/.github/workflows/wdi5-tests_core.yml +++ b/.github/workflows/wdi5-tests_core.yml @@ -48,7 +48,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm set-script prepare "" + npm pkg set scripts.prepare "" npm ci # build things diff --git a/.github/workflows/wdi5-tests_fe-app.yml b/.github/workflows/wdi5-tests_fe-app.yml index c7e7c63c..450151c9 100644 --- a/.github/workflows/wdi5-tests_fe-app.yml +++ b/.github/workflows/wdi5-tests_fe-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm set-script prepare "" + npm pkg set scripts.prepare "" npm ci # build things diff --git a/.github/workflows/wdi5-tests_js-app.yml b/.github/workflows/wdi5-tests_js-app.yml index bb4fcf5b..db16f8a9 100644 --- a/.github/workflows/wdi5-tests_js-app.yml +++ b/.github/workflows/wdi5-tests_js-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm set-script prepare "" + npm pkg set scripts.prepare "" npm ci # build things diff --git a/.github/workflows/wdi5-tests_ts-app.yml b/.github/workflows/wdi5-tests_ts-app.yml index c86bfc0c..fd98aa42 100644 --- a/.github/workflows/wdi5-tests_ts-app.yml +++ b/.github/workflows/wdi5-tests_ts-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm set-script prepare "" + npm pkg set scripts.prepare "" npm ci # build things From 1a2774645799595a5472b20df4a60ff504591fec Mon Sep 17 00:00:00 2001 From: "dominik.feininger" Date: Fri, 11 Nov 2022 08:56:40 +0100 Subject: [PATCH 06/35] chore(pipeline): update set script for npm v9 --- .github/workflows/wdi5-tests_core.yml | 2 +- .github/workflows/wdi5-tests_fe-app.yml | 2 +- .github/workflows/wdi5-tests_js-app.yml | 2 +- .github/workflows/wdi5-tests_ts-app.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/wdi5-tests_core.yml b/.github/workflows/wdi5-tests_core.yml index 117f366e..b6e4ff86 100644 --- a/.github/workflows/wdi5-tests_core.yml +++ b/.github/workflows/wdi5-tests_core.yml @@ -48,7 +48,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm pkg set scripts.prepare "" + npm pkg delete scripts.prepare npm ci # build things diff --git a/.github/workflows/wdi5-tests_fe-app.yml b/.github/workflows/wdi5-tests_fe-app.yml index 450151c9..8331243f 100644 --- a/.github/workflows/wdi5-tests_fe-app.yml +++ b/.github/workflows/wdi5-tests_fe-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm pkg set scripts.prepare "" + npm pkg delete scripts.prepare npm ci # build things diff --git a/.github/workflows/wdi5-tests_js-app.yml b/.github/workflows/wdi5-tests_js-app.yml index db16f8a9..ca498452 100644 --- a/.github/workflows/wdi5-tests_js-app.yml +++ b/.github/workflows/wdi5-tests_js-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm pkg set scripts.prepare "" + npm pkg delete scripts.prepare npm ci # build things diff --git a/.github/workflows/wdi5-tests_ts-app.yml b/.github/workflows/wdi5-tests_ts-app.yml index fd98aa42..6e9a770c 100644 --- a/.github/workflows/wdi5-tests_ts-app.yml +++ b/.github/workflows/wdi5-tests_ts-app.yml @@ -57,7 +57,7 @@ jobs: # install both module + sample app(s) deps - name: install packages (wdi5 + sample app(s)) run: | - npm pkg set scripts.prepare "" + npm pkg delete scripts.prepare npm ci # build things From 426430dad2d14a930f2127992bfca1bfaba003c5 Mon Sep 17 00:00:00 2001 From: Constantin Lebrecht Date: Fri, 11 Nov 2022 11:36:39 +0100 Subject: [PATCH 07/35] feat: add Office365 authentication method --- .../authentication/Office365Authenticator.ts | 34 +++++++++++++++++++ src/lib/wdi5-bridge.ts | 4 +++ src/types/wdi5.types.ts | 33 ++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/lib/authentication/Office365Authenticator.ts diff --git a/src/lib/authentication/Office365Authenticator.ts b/src/lib/authentication/Office365Authenticator.ts new file mode 100644 index 00000000..6e9ff24a --- /dev/null +++ b/src/lib/authentication/Office365Authenticator.ts @@ -0,0 +1,34 @@ +import Authenticator from "./Authenticator" +class Office365Authenticator extends Authenticator { + staySignedIn: boolean + constructor(options) { + super() + this.usernameSelector = options.usernameSelector ?? "[name=loginfmt]" + this.passwordSelector = options.passwordSelector ?? "[name=passwd]" + this.submitSelector = options.submitSelector ?? "[data-report-event=Signin_Submit]" + this.staySignedIn = options.staySignedIn ?? true + } + + async login() { + const username = await $(this.usernameSelector) + await username.setValue(process.env.wdi5_username) + await $(this.submitSelector).click() + await browser.waitUntil(async () => await (await $(this.passwordSelector)).isClickable(), { + timeout: 5000, + timeoutMsg: "Password field is not visible" + }) + const password = await $(this.passwordSelector) + await password.setValue(process.env.wdi5_password) + await $(this.submitSelector).click() + if (this.staySignedIn) { + await browser.waitUntil(async () => await (await $("#KmsiDescription")).isClickable(), { + timeout: 5000, + timeoutMsg: + "StaySignedIn step is not visible. If this step doesnt exist, set in wdi5 configuration 'staySignedIn' option to false." + }) + await $(this.submitSelector).click() + } + } +} + +export default Office365Authenticator diff --git a/src/lib/wdi5-bridge.ts b/src/lib/wdi5-bridge.ts index 4bb73c88..f1bfb2c6 100644 --- a/src/lib/wdi5-bridge.ts +++ b/src/lib/wdi5-bridge.ts @@ -19,6 +19,7 @@ import { Logger as _Logger } from "./Logger" import BTPAuthenticator from "./authentication/BTPAuthenticator" import BasicAuthenticator from "./authentication/BasicAuthenticator" import CustomAuthenticator from "./authentication/CustomAuthenticator" +import Office365Authenticator from "./authentication/Office365Authenticator" const Logger = _Logger.getInstance() @@ -149,6 +150,9 @@ export async function authenticate(options) { case "BasicAuth": await BasicAuthenticator.login() break + case "Office365": + await new Office365Authenticator(options).login() + break case "custom": await new CustomAuthenticator(options).login() default: diff --git a/src/types/wdi5.types.ts b/src/types/wdi5.types.ts index 8d470e4f..85de380e 100644 --- a/src/types/wdi5.types.ts +++ b/src/types/wdi5.types.ts @@ -47,6 +47,39 @@ export interface wdi5Config extends WebdriverIO.Config { */ waitForUI5Timeout?: number } + capabilities: wdi5Capabilites[] +} + +/** + * the "wdi5" prefix is to comply with W3C standards + */ +interface wdi5Capabilites extends WebDriver.DesiredCapabilities { + "wdi5:authentication"?: BTPAuthenticator | BasicAuthAuthenticator | CustomAuthenticator | Office365Authenticator +} + +type BTPAuthenticator = { + provider: "BTP" + usernameSelector?: string + passwordSelector?: string + submitSelector?: string +} + +type BasicAuthAuthenticator = { + provider: "BasicAuth" +} + +type CustomAuthenticator = { + provider: "custom" + usernameSelector: string + passwordSelector: string + submitSelector: string +} + +type Office365Authenticator = { + provider: "Office365" + usernameSelector?: string + passwordSelector?: string + submitSelector?: string } interface wdi5ControlSelector { From 875922bd0c05319e2f153356e89ba105c744cc11 Mon Sep 17 00:00:00 2001 From: scoen Date: Fri, 11 Nov 2022 15:24:43 +0100 Subject: [PATCH 08/35] feat(auth): multi remote support - enhance super Authenticator for multiRemote support - introduce getter methods for username and password - update already existing authenticators for multi remote Co-authored-by: Volker Buzek Co-authored-by: Constantin Lebrecht --- examples/ui5-ts-app/package.json | 4 ++- .../ui5-ts-app/test/e2e/multiremote.test.ts | 23 +++++++++++++++ src/lib/authentication/Authenticator.ts | 29 +++++++++++++++++++ src/lib/authentication/BTPAuthenticator.ts | 24 ++++++++------- src/lib/authentication/BasicAuthenticator.ts | 13 +++++---- src/lib/authentication/CustomAuthenticator.ts | 16 +++++----- .../authentication/Office365Authenticator.ts | 12 ++++---- src/lib/wdi5-bridge.ts | 10 +++---- src/service.ts | 3 ++ 9 files changed, 99 insertions(+), 35 deletions(-) create mode 100644 examples/ui5-ts-app/test/e2e/multiremote.test.ts diff --git a/examples/ui5-ts-app/package.json b/examples/ui5-ts-app/package.json index 52f1be6d..d5148f13 100644 --- a/examples/ui5-ts-app/package.json +++ b/examples/ui5-ts-app/package.json @@ -8,12 +8,13 @@ "start": "npm-run-all --parallel watch:ts start:ui5", "watch:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files --watch", "start:ui5": "ui5 serve --port 8080", - "test": "run-s test:authentication", + "test": "run-s test:*", "test:basic": "wdio run wdio-ui5.conf.ts", "test:authentication": "run-s authentication:*", "authentication:btp": "wdio run test/e2e/authentication/wdio-btp-authentication.conf.ts", "authentication:basic-auth": "wdio run test/e2e/authentication/wdio-basic-auth-authentication.conf.ts", "authentication:custom": "wdio run test/e2e/authentication/wdio-custom-authentication.conf.ts", + "authentication:multiRemote": "wdio run test/e2e/authentication/wdio-btp-authentication-multiremote.conf.ts", "build:ts": "babel src --out-dir webapp --source-maps true --extensions \".ts,.js\" --copy-files", "build:ui5": "ui5 build --clean-dest", "build:mtar": "mv dist approuter/webapp && mbt build", @@ -30,6 +31,7 @@ "@types/jquery": "3.5.14", "babel-preset-transform-ui5": "^7.0.5", "mbt": "^1.2.18", + "ts-deepmerge": "^5.0.0", "ui5-middleware-simpleproxy": "^0.9.0" }, "ui5": { diff --git a/examples/ui5-ts-app/test/e2e/multiremote.test.ts b/examples/ui5-ts-app/test/e2e/multiremote.test.ts new file mode 100644 index 00000000..dee3e55f --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/multiremote.test.ts @@ -0,0 +1,23 @@ +import Button from "sap/m/Button" +import { wdi5Selector } from "wdio-ui5-service/dist/types/wdi5.types" + +describe("Basic", async () => { + it("browser.allControls: check number of buttons", async () => { + // const allButtonsSelector: wdi5Selector = { + // selector: { + // controlType: "sap.ui.webc.main.Button", + // viewName: "test.Sample.tsapp.view.Main" + // } + // } + // // @ts-ignore + // const allButtonsTwo = (await browser.two.allControls(allButtonsSelector)) as unknown as Array