diff --git a/.github/workflows/wdi5-tests_ts-app.yml b/.github/workflows/wdi5-tests_ts-app.yml index cf6438d0..38f20803 100644 --- a/.github/workflows/wdi5-tests_ts-app.yml +++ b/.github/workflows/wdi5-tests_ts-app.yml @@ -68,3 +68,7 @@ jobs: # this includes test for late-injecting wdi5 - name: test ts-app run: npm run test-h:ts-app + + # this runs against the deployed wdi5 TS sample app + - name: test devtools support + run: npm run test:protocol diff --git a/examples/ui5-ts-app/package.json b/examples/ui5-ts-app/package.json index 7b707942..827dedc4 100644 --- a/examples/ui5-ts-app/package.json +++ b/examples/ui5-ts-app/package.json @@ -18,6 +18,9 @@ "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", + "test:protocol": "run-p \"protocol:* -- --headless\"", + "protocol:devtools": "wdio run test/e2e/protocol/wdio-ui5-devtools.conf.ts", + "protocol:webdriver": "wdio run test/e2e/protocol/wdio-ui5-webdriver.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/Protocol.test.ts b/examples/ui5-ts-app/test/e2e/Protocol.test.ts new file mode 100644 index 00000000..f1eb2152 --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/Protocol.test.ts @@ -0,0 +1,47 @@ +import { wdi5Selector } from "wdio-ui5-service/dist/types/wdi5.types" +import Button from "sap/ui/webc/main/Button" + +describe("Protocol", async () => { + it("should see the button text - wdio", async () => { + const buttonWDI5 = await getButtonOnPage1() + const buttonWDIO = await buttonWDI5.getWebElement() + const buttonTextWDIO: string = await buttonWDIO.getText() + expect(buttonTextWDIO).toEqual("to Other view") + }) + + it("should see the button text - wdi5 - native UI5 method", async () => { + const buttonWDI5 = (await getButtonOnPage1()) as unknown as Button + const buttonText: string = await buttonWDI5.getText() + expect(buttonText).toEqual("to Other view") + }) + + it("should press the button - wdi5 - control method", async () => { + const buttonWDI5 = await getButtonOnPage1() + await buttonWDI5.press() + }) + + it("should see the next page", async () => { + const buttonWDI5 = await getButtonOnPage2() + await buttonWDI5.press() + }) + + async function getButtonOnPage1() { + const wdi5Button: wdi5Selector = { + forceSelect: true, + selector: { + id: "__component0---Main--NavFwdButton" + } + } + return await browser.asControl(wdi5Button) + } + + async function getButtonOnPage2() { + const wdi5Button: wdi5Selector = { + forceSelect: true, + selector: { + id: "__component0---Other--idAddLineItemButton" + } + } + return await browser.asControl(wdi5Button) + } +}) 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 index 17c61271..18c796fe 100644 --- 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 @@ -11,7 +11,7 @@ const capability: wdi5Capabilites = { "goog:chromeOptions": { args: process.argv.indexOf("--headless") > -1 - ? ["--headless"] + ? ["headless", "disable-gpu"] : process.argv.indexOf("--debug") > -1 ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] : ["window-size=1440,800"] diff --git a/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication-multiremote.conf.ts b/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication-multiremote.conf.ts index 6784a7d2..48b9633c 100644 --- a/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication-multiremote.conf.ts +++ b/examples/ui5-ts-app/test/e2e/authentication/wdio-btp-authentication-multiremote.conf.ts @@ -12,7 +12,7 @@ const multiRemoteCapability: wdi5MultiRemoteCapability = { "goog:chromeOptions": { args: process.argv.indexOf("--headless") > -1 - ? ["--headless"] + ? ["headless", "disable-gpu"] : process.argv.indexOf("--debug") > -1 ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] : ["window-size=1440,800"] 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 index 2591f26b..05a1b8f6 100644 --- 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 @@ -11,7 +11,7 @@ const capability: wdi5Capabilites = { "goog:chromeOptions": { args: process.argv.indexOf("--headless") > -1 - ? ["--headless"] + ? ["headless", "disable-gpu"] : process.argv.indexOf("--debug") > -1 ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] : ["window-size=1440,800"] 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 index aa704293..d07fb6af 100644 --- 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 @@ -18,7 +18,7 @@ const capability: wdi5Capabilites = { "goog:chromeOptions": { args: process.argv.indexOf("--headless") > -1 - ? ["--headless"] + ? ["headless", "disable-gpu"] : process.argv.indexOf("--debug") > -1 ? ["window-size=1440,800", "--auto-open-devtools-for-tabs"] : ["window-size=1440,800"] diff --git a/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-devtools.conf.ts b/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-devtools.conf.ts new file mode 100644 index 00000000..42ea103f --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-devtools.conf.ts @@ -0,0 +1,27 @@ +import { wdi5Config } from "wdio-ui5-service/dist/types/wdi5.types" +import { setDefaultResultOrder } from "node:dns" +export const config: wdi5Config = { + baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/no-auth/", + services: ["ui5"] /* no drivers, so wdio is falling back to devtools + puppeteer*/, + specs: ["test/e2e/Protocol.test.ts"], + capabilities: [ + { + browserName: "chromium", + "goog:chromeOptions": { + args: process.argv.indexOf("--headless") > -1 ? ["headless", "disable-gpu"] : [] + }, + acceptInsecureCerts: true + } + ], + waitforTimeout: 29000, + logLevel: "error", + reporters: ["spec"], + framework: "mocha", + mochaOpts: { + timeout: 29000 + }, + + beforeSession: () => { + setDefaultResultOrder("ipv4first") + } +} diff --git a/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-webdriver.conf.ts b/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-webdriver.conf.ts new file mode 100644 index 00000000..cac53234 --- /dev/null +++ b/examples/ui5-ts-app/test/e2e/protocol/wdio-ui5-webdriver.conf.ts @@ -0,0 +1,23 @@ +import { wdi5Config } from "wdio-ui5-service/dist/types/wdi5.types" + +export const config: wdi5Config = { + baseUrl: "https://wdi5-sample-app.cfapps.eu20.hana.ondemand.com/no-auth/", + services: ["chromedriver", "ui5"], + specs: ["test/e2e/Protocol.test.ts"], + capabilities: [ + { + browserName: "chrome", + "goog:chromeOptions": { + args: process.argv.indexOf("--headless") > -1 ? ["headless", "disable-gpu"] : [] + }, + acceptInsecureCerts: true + } + ], + waitforTimeout: 29000, + logLevel: "error", + reporters: ["spec"], + framework: "mocha", + mochaOpts: { + timeout: 29000 + } +} diff --git a/package.json b/package.json index 9cb6251f..600c88de 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,8 @@ "_test:fe-app": "wait-on tcp:8088 && npm run test:wdi5 --workspace=examples/fe-app", "test:fe-app": "run-p -r _startApp:fe _test:fe-app", "test:auth": "npm run test-h:authentication -w examples/ui5-ts-app", + "//test:protocol": "runs the same test with webdriver and devtools protocol", + "test:protocol": "npm run test:protocol -w examples/ui5-ts-app", "test": "cross-env TS_NODE_PROJECT=\"test/tsconfig.json\" mocha", "prepare": "husky install", "release": "standard-version", diff --git a/src/lib/wdi5-control.ts b/src/lib/wdi5-control.ts index 87c96e43..23d7e3ef 100644 --- a/src/lib/wdi5-control.ts +++ b/src/lib/wdi5-control.ts @@ -1,5 +1,5 @@ import * as util from "util" - +import { ELEMENT_KEY } from "webdriverio/build/constants" import { clientSide_getControl } from "../../client-side-js/getControl" import { clientSide_interactWithControl } from "../../client-side-js/interactWithControl" import { clientSide_executeControlMethod } from "../../client-side-js/executeControlMethod" @@ -9,7 +9,6 @@ import { clientSide_ui5Response, wdi5ControlMetadata, wdi5Selector } from "../ty import { Logger as _Logger } from "./Logger" import { wdioApi } from "./wdioApi" import { WDI5Object } from "./wdi5-object" - const Logger = _Logger.getInstance() /** @@ -659,6 +658,23 @@ export class WDI5Control { } const _result = (await clientSide_getControl(controlSelector, this._browserInstance)) as clientSide_ui5Response + + // When the WebDriver protocol is not used, the domElement is not set accordingly (via devtool protocol) + // Therefore we get element reference by calling browser execute function manually + if (_result.status === 0 && !_result.domElement[ELEMENT_KEY]) { + const elementReference = (await this._browserInstance.execute((id) => { + const webElement: Node = document.evaluate( + `//*[@id='${id}']`, + document, + null, + XPathResult.FIRST_ORDERED_NODE_TYPE, + null + ).singleNodeValue + return webElement + }, _result.id)) as unknown as WebdriverIO.Element + _result.domElement = elementReference + } + const { status, domElement, id, aProtoFunctions, className } = _result if (status === 0 && id) {