Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow for async client-side controller functions #423

Merged
merged 4 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions client-side-js/executeObjectMethod.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,35 @@ async function clientSide_executeObjectMethod(uuid, methodName, args) {
(uuid, methodName, args, done) => {
window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
() => {
// this callback is denoted "async" even though it is truely not
// but what other way to `await` a potentially async UI5 managed object fn in here?
async () => {
// DOM to UI5
const oObject = window.wdi5.objectMap[uuid]

// execute the function
// TODO: if (methodName === "getName") { debugger }
let result = oObject[methodName].apply(oObject, args)
let result
let threw = false
let threwMessage = ""
if (oObject[methodName].constructor.name === "AsyncFunction") {
try {
result = await oObject[methodName].apply(oObject, args)
} catch (error) {
threw = true
threwMessage = JSON.stringify(error)
window.wdi5.Log.error(threwMessage)
}
} else {
result = oObject[methodName].apply(oObject, args)
}

// async message call rejected
if (threw) {
done({ status: 1, message: threwMessage })
}
// result mus be a primitive
if (window.wdi5.isPrimitive(result)) {
else if (window.wdi5.isPrimitive(result)) {
// getter
done({ status: 0, result: result, returnType: "result" })
} else {
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/getObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async function clientSide_getObject(uuid) {
if (!object) {
const errorMessage = `[browser wdi5] ERR: no object with uuid: ${uuid} found`
window.wdi5.Log.error(errorMessage)
done({ status: 1, messsage: errorMessage })
done({ status: 1, message: errorMessage })
}

let className = ""
Expand Down
11 changes: 11 additions & 0 deletions examples/ui5-ts-app/src/controller/Main.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,15 @@ export default class Main extends BaseController {
navFwd(): any {
return this.getOwnerComponent().getRouter().navTo("RouteOther")
}

async asyncFn(): Promise<number> {
return new Promise((resolve) => {
resolve(10)
})
}
async asyncRejectFn(): Promise<number> {
return new Promise((resolve, reject) => {
reject("meh")
})
}
}
44 changes: 44 additions & 0 deletions examples/ui5-ts-app/test/e2e/Basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import Button from "sap/m/Button"
import Page from "sap/m/Page"
import Controller from "sap/ui/core/mvc/Controller"
import View from "sap/ui/core/mvc/View"
import { wdi5Selector } from "wdio-ui5-service/dist/types/wdi5.types"
import { wdi5 } from "wdio-ui5-service"
import * as sinon from "sinon"

const Logger = wdi5.getLogger()

describe("Basic", async () => {
it("browser.allControls: check number of buttons", async () => {
Expand All @@ -13,4 +20,41 @@ describe("Basic", async () => {
const allButtons = (await browser.allControls(allButtonsSelector)) as unknown as Array<Button>
expect(allButtons.length).toEqual(1)
})

it("should resolve an async Controller function", async () => {
const selector: wdi5Selector = {
selector: {
id: "page",
viewName: "test.Sample.tsapp.view.Main"
}
}
const view: unknown = await (browser.asControl(selector) as unknown as Page).getParent()
const controller: Controller = await (view as View).getController()

// @ts-ignore this async fn lives in an not properly typed controller
const number = await controller.asyncFn()
expect(number).toEqual(10)
})

it("should catch an erroneous async Controller function properly", async () => {
const sandbox = sinon.createSandbox()
sandbox.spy(Logger, "error")

const selector: wdi5Selector = {
selector: {
id: "page",
viewName: "test.Sample.tsapp.view.Main"
}
}
const view: unknown = await (browser.asControl(selector) as unknown as Page).getParent()
const controller: Controller = await (view as View).getController()

// @ts-ignore this async fn lives in an not properly typed controller
await controller.asyncRejectFn()
expect(
(Logger.error as sinon.SinonSpy).calledWith('call of asyncRejectFn failed because of: "meh"')
).toBeTruthy()

sandbox.restore()
})
})