Skip to content

Commit

Permalink
fix: performance
Browse files Browse the repository at this point in the history
  • Loading branch information
Siolto committed Feb 11, 2025
1 parent 8336ccb commit e76d09f
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 125 deletions.
2 changes: 1 addition & 1 deletion client-side-js/_checkForUI5Ready.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
async function clientSide__checkForUI5Ready(browserInstance) {
return await browserInstance.execute(async () => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
4 changes: 2 additions & 2 deletions client-side-js/allControls.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ async function clientSide_allControls(controlSelector, browserInstance) {
}

try {
await window.wdi5.waitForUI5(waitForUI5Options)
await window.bridge.waitForUI5(waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}

window.wdi5.Log.info("[browser wdi5] locating " + JSON.stringify(controlSelector))
controlSelector.selector = window.wdi5.createMatcher(controlSelector.selector)
let domElements;
let domElements

try {
domElements = await window.bridge.findAllDOMElementsByControlSelector(controlSelector)
Expand Down
202 changes: 98 additions & 104 deletions client-side-js/executeControlMethod.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,118 +13,112 @@ if (global.browser) {
async function executeControlMethod(webElement, methodName, browserInstance, args) {
return await browserInstance.execute(
async (webElement, methodName, args) => {
return new Promise(async (resolve, reject) => {
await window.wdi5.waitForUI5(
window.wdi5.waitForUI5Options,
() => {
// DOM to UI5
const oControl = window.wdi5.getUI5CtlForWebObj(webElement)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
// window.wdi5.errorHandling.bind(this, null, reject)

// execute the function
let result = oControl[methodName].apply(oControl, args)
const metadata = oControl.getMetadata()
// DOM to UI5
const oControl = window.wdi5.getUI5CtlForWebObj(webElement)

if (Array.isArray(result)) {
if (result.length === 0) {
resolve({ status: 0, result: result, returnType: "empty" })
} else if (result[0]?.getParent) {
// expect the method call delivers non-primitive results (like getId())
// but delivers a complex/structured type
// -> currenlty, only getAggregation(...) is supported
// read classname eg. sap.m.ComboBox
controlType = oControl.getMetadata()._sClassName
// execute the function
let result = oControl[methodName].apply(oControl, args)
const metadata = oControl.getMetadata()

result = window.wdi5.createControlIdMap(result, controlType)
resolve({ status: 0, result: result, returnType: "aggregation" })
} else {
resolve({ status: 0, result: result, returnType: "result" })
}
} else {
// ui5 api <control>.focus() doesn't have return value
if (methodName === "focus" && result === undefined) {
resolve({
status: 0,
result: `called focus() on wdi5 representation of a ${metadata.getElementName()}`,
returnType: "element"
})
} else if (methodName === "exec" && result && result.status > 0) {
resolve({
status: result.status,
message: result.message
})
} else if (result === undefined || result === null) {
resolve({
status: 1,
result: `function ${methodName} does not exist on control ${metadata.getElementName()}!`,
returnType: "none"
})
} else {
if (window.wdi5.isPrimitive(result)) {
resolve({ status: 0, result: result, returnType: "result" })
} else if (
// we have an object that is not a UI5 control
typeof result === "object" &&
result !== null &&
!(result instanceof sap.ui.core.Control) &&
!(result instanceof sap.ui.core.Item)
) {
// save before manipulate
const uuid = window.wdi5.saveObject(result)
if (Array.isArray(result)) {
if (result.length === 0) {
return { status: 0, result: result, returnType: "empty" }
} else if (result[0]?.getParent) {
// expect the method call delivers non-primitive results (like getId())
// but delivers a complex/structured type
// -> currenlty, only getAggregation(...) is supported
// read classname eg. sap.m.ComboBox
controlType = oControl.getMetadata()._sClassName

result = window.wdi5.createControlIdMap(result, controlType)
return { status: 0, result: result, returnType: "aggregation" }
} else {
return { status: 0, result: result, returnType: "result" }
}
} else {
// ui5 api <control>.focus() doesn't have return value
if (methodName === "focus" && result === undefined) {
return {
status: 0,
result: `called focus() on wdi5 representation of a ${metadata.getElementName()}`,
returnType: "element"
}
} else if (methodName === "exec" && result && result.status > 0) {
return {
status: result.status,
message: result.message
}
} else if (result === undefined || result === null) {
return {
status: 1,
result: `function ${methodName} does not exist on control ${metadata.getElementName()}!`,
returnType: "none"
}
} else {
if (window.wdi5.isPrimitive(result)) {
return { status: 0, result: result, returnType: "result" }
} else if (
// we have an object that is not a UI5 control
typeof result === "object" &&
result !== null &&
!(result instanceof sap.ui.core.Control) &&
!(result instanceof sap.ui.core.Item)
) {
// save before manipulate
const uuid = window.wdi5.saveObject(result)

// FIXME: extract, collapse and remove cylic in 1 step
// extract the methods first
const aProtoFunctions = window.wdi5.retrieveControlMethods(result, true)
// FIXME: extract, collapse and remove cylic in 1 step
// extract the methods first
const aProtoFunctions = window.wdi5.retrieveControlMethods(result, true)

// flatten the prototype so we have all funcs available
const collapsed = window.wdi5.collapseObject(result)
// exclude cyclic references
const collapsedAndNonCyclic = JSON.parse(
JSON.stringify(collapsed, window.wdi5.getCircularReplacer())
)
// remove all empty Array elements, inlcuding private keys (starting with "_")
const semanticCleanedElements =
window.wdi5.removeEmptyElements(collapsedAndNonCyclic)
// flatten the prototype so we have all funcs available
const collapsed = window.wdi5.collapseObject(result)
// exclude cyclic references
const collapsedAndNonCyclic = JSON.parse(
JSON.stringify(collapsed, window.wdi5.getCircularReplacer())
)
// remove all empty Array elements, inlcuding private keys (starting with "_")
const semanticCleanedElements = window.wdi5.removeEmptyElements(collapsedAndNonCyclic)

resolve({
status: 0,
object: semanticCleanedElements,
returnType: "object",
aProtoFunctions: aProtoFunctions,
uuid: uuid,
nonCircularResultObject: semanticCleanedElements
})
} else if (
typeof result === "object" &&
result !== null &&
// wdi5 returns a wdi5 control if the UI5 api return its control
// allows method chaining
!(result instanceof sap.ui.base.Object)
) {
resolve({
status: 2,
returnType: "unknown"
})
} else {
// we got ourselves a regular UI5 control
// check that we're not working against ourselves :)
if (result && result.getId && oControl.getId() !== result.getId()) {
// ui5 function like get parent might return another ui5 control -> return it to check with this wdi5 instance
result = window.wdi5.createControlId(result)
resolve({ status: 0, result: result, returnType: "newElement" })
} else {
resolve({
status: 0,
result: `instance of wdi5 representation of a ${metadata.getElementName()}`,
returnType: "element"
})
}
}
return {
status: 0,
object: semanticCleanedElements,
returnType: "object",
aProtoFunctions: aProtoFunctions,
uuid: uuid,
nonCircularResultObject: semanticCleanedElements
}
} else if (
typeof result === "object" &&
result !== null &&
// wdi5 returns a wdi5 control if the UI5 api return its control
// allows method chaining
!(result instanceof sap.ui.base.Object)
) {
return {
status: 2,
returnType: "unknown"
}
} else {
// we got ourselves a regular UI5 control
// check that we're not working against ourselves :)
if (result && result.getId && oControl.getId() !== result.getId()) {
// ui5 function like get parent might return another ui5 control -> return it to check with this wdi5 instance
result = window.wdi5.createControlId(result)
return { status: 0, result: result, returnType: "newElement" }
} else {
return {
status: 0,
result: `instance of wdi5 representation of a ${metadata.getElementName()}`,
returnType: "element"
}
}
},
window.wdi5.errorHandling.bind(this, null, reject)
)
})
}
}
}
},
webElement,
methodName,
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/executeObjectMethod.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ async function clientSide_executeObjectMethod(uuid, methodName, args) {
return await browser.execute(
async (uuid, methodName, args) => {
return new Promise(async (resolve, reject) => {
await window.wdi5.waitForUI5(
await window.bridge.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?
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/fireEvent.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ async function clientSide_fireEvent(webElement, eventName, oOptions, browserInst
return await browserInstance.execute(
async (webElement, eventName, oOptions) => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/getControl.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ async function clientSide_getControl(controlSelector, browserInstance) {
}

try {
await window.wdi5.waitForUI5(waitForUI5Options)
await window.bridge.waitForUI5(waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/getObject.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ async function clientSide_getObject(uuid) {
const waitForUI5Options = Object.assign({}, window.wdi5.waitForUI5Options)

try {
await window.wdi5.waitForUI5(waitForUI5Options)
await window.bridge.waitForUI5(waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
5 changes: 2 additions & 3 deletions client-side-js/getSelectorForElement.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@
async function clientSide_getSelectorForElement(oOptions, browserInstance) {
return await browserInstance.execute(async (oOptions) => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}

window.wdi5.Log.info("[browser wdi5] locating domElement")
let controlSelector
try {
controlSelector = await window.bridge
.findControlSelectorByDOMElement(oOptions)
controlSelector = await window.bridge.findControlSelectorByDOMElement(oOptions)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
2 changes: 1 addition & 1 deletion client-side-js/interactWithControl.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ async function clientSide_interactWithControl(oOptions, browserInstance) {
browserInstance = await Promise.resolve(browserInstance)
return await browserInstance.execute(async (oOptions) => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
} catch (error) {
return window.wdi5.errorHandling(error)
}
Expand Down
12 changes: 4 additions & 8 deletions client-side-js/testLibrary.cjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
async function initOPA(pageObjectConfig, browserInstance) {
return await browserInstance.execute(async (pageObjectConfig) => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)

const pageConfig = {}
Object.keys(pageObjectConfig).map((pageKey) => {
Expand Down Expand Up @@ -31,21 +31,17 @@ async function initOPA(pageObjectConfig, browserInstance) {
// different error handling for the test library
return ["error", error.toString()]
}




}, pageObjectConfig)
}
async function emptyQueue(browserInstance) {
return await browserInstance.execute(async () => {
try {
debugger
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)
await sap.ui.test.Opa.emptyQueue()
const feLogs = window.fe_bridge.Log
window.fe_bridge.Log = []
return ({ type: "success", feLogs: feLogs })
return { type: "success", feLogs: feLogs }
} catch (error) {
return {
type: "error",
Expand All @@ -61,7 +57,7 @@ async function emptyQueue(browserInstance) {
async function addToQueue(methodCalls, browserInstance) {
return await browserInstance.execute(async (methodCalls) => {
try {
await window.wdi5.waitForUI5(window.wdi5.waitForUI5Options)
await window.bridge.waitForUI5(window.wdi5.waitForUI5Options)

for (const methodCall of methodCalls) {
let scope
Expand Down
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 @@ -3,7 +3,7 @@ const { baseConfig } = require("./wdio.base.conf")
const merge = require("deepmerge")

const _config = {
specs: [join("..", "webapp", "test", "e2e", "**/*.test.js")],
specs: [join("..", "webapp", "test", "e2e", "**/basic.test.js")],
exclude: [
join("..", "webapp", "test", "e2e", "ui5-late.test.js"),
join("..", "webapp", "test", "e2e", "multiremote.test.js")
Expand Down
2 changes: 1 addition & 1 deletion examples/ui5-js-app/e2e-test-config/wdio.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ exports.baseConfig = {
maxInstances: 4,
browserName: "chrome",
acceptInsecureCerts: true,
// "wdio:enforceWebDriverClassic": true,
"wdio:enforceWebDriverClassic": true,
"goog:chromeOptions": {
args:
process.argv.indexOf("--headless") > -1
Expand Down

0 comments on commit e76d09f

Please sign in to comment.