Skip to content

Commit

Permalink
feat: add option to ignore urls for auto waiting (#575)
Browse files Browse the repository at this point in the history
[skip ci] more commits to go into the next release
  • Loading branch information
sebbi08 authored Jan 15, 2024
1 parent 1d827b9 commit 4f1255c
Show file tree
Hide file tree
Showing 12 changed files with 927 additions and 24 deletions.
55 changes: 55 additions & 0 deletions client-side-js/injectXHRPatch.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
async function clientSide_injectXHRPatch(config, browserInstance) {
return await browserInstance.executeAsync((config, done) => {
const originalFetch = window.fetch

const ignoreAutoWaitUrls = config.wdi5.ignoreAutoWaitUrls
function checkURL(url) {
return ignoreAutoWaitUrls?.map((regex) => new RegExp(regex))?.some((regex) => url.match(regex)) || false
}
const imports = ["sap/ui/thirdparty/sinon", "sap/ui/test/autowaiter/_XHRWaiter"]
if (window.compareVersions.compare(sap.ui.version, "1.114.0", ">")) {
imports.push("sap/ui/test/autowaiter/_fetchWaiter")
}

//Load the XHRWaiter before our overwrite so we are called first
sap.ui.require(imports, function (sinon, _XHRWaiter, _fetchWaiter) {
// Hook into XHR open for sinon XHRs
const fnOriginalFakeOpen = sinon.FakeXMLHttpRequest.prototype.open
sinon.FakeXMLHttpRequest.prototype.open = function () {
return fnOriginalFakeOpen.apply(this, hooktoXHROpen.apply(this, arguments))
}

// Hook into XHR open for regular XHRs
const fnOriginalOpen = XMLHttpRequest.prototype.open
XMLHttpRequest.prototype.open = function () {
return fnOriginalOpen.apply(this, hooktoXHROpen.apply(this, arguments))
}

function hooktoXHROpen(method, url, async) {
//The ignore property will force the OPA5 _XHRWaiter to ignore certain calls for auto waiting
//https://github.com/SAP/openui5/blob/45e49887f632d0a8a8ef195bd3edf10eb0be9015/src/sap.ui.core/src/sap/ui/test/autowaiter/_XHRWaiter.js
//This ist the XHR request instance so setting it here will only affect the specific request
this.ignored = checkURL(url)

return arguments
}
if (_fetchWaiter !== undefined) {
const sapFetch = window.fetch

window.fetch = function (resource) {
const url = typeof resource === "object" ? resource.url : resource
if (checkURL(url)) {
return originalFetch.apply(this, arguments)
} else {
return sapFetch.apply(this, arguments)
}
}
}
done(true)
})
}, config)
}

module.exports = {
clientSide_injectXHRPatch
}
11 changes: 10 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ exports.config = {
logLevel: "verbose", // [optional] error | verbose | silent, default: "error"
skipInjectUI5OnStart: false, // [optional] {boolean}, default: false; true when UI5 is not on the start page, you need to later call <wdioUI5service>.injectUI5() manually
waitForUI5Timeout: 15000, // [optional] {number}, default: 15000; maximum waiting time in milliseconds while checking for UI5 availability
btpWorkZoneEnablement: false // [optional] {boolean}, default: false; whether to instruct wdi5 to inject itself in both the SAP Build Workzone, standard edition, shell and app
btpWorkZoneEnablement: false, // [optional] {boolean}, default: false; whether to instruct wdi5 to inject itself in both the SAP Build Workzone, standard edition, shell and app
ignoreAutoWaitUrls: [] // [optional] {string[]}, default: []; Array of regex to ignore certain XHR/Fetch calls wile autowaiting
}
// ...
}
Expand Down Expand Up @@ -133,6 +134,14 @@ Number in milliseconds (default: `15000`) to wait for UI5-related operations wit
Boolean setting to trigger injecting `wdi5` into both the shell and the app when used with the SAP Build Workzone, standard edition.
Recommended complement is to also [configure IAS Authentication](authentication?id=sap-cloud-identity-services-identity-authentication): as SAP Build requires its own Identity Provider (most likely provided by using an IAS tenant), you'll have to configure authentication against that as well in `wdi5`.

### `ignoreAutoWaitUrls`

Array of URLs (as strings), either relative or absolute. `RegEx` are supported.
Querying the URLs will be excluded from the UI5 lifecycle sync. Meaning: no Test code will wait until querying the URLs resolve.
Typical use case is "longpolling" requests that continuously update your app.

!> Be careful not to add too many URLs here as this might make the tests unreliable

## `package.json`

Not required, but as a convention, put a `test` or `wdi5` script into your UI5.app's `package.json` to start `wdi5/wdio`.
Expand Down
5 changes: 4 additions & 1 deletion examples/ui5-js-app/e2e-test-config/wdio-ui5tooling.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ const merge = require("deepmerge")

const _config = {
specs: [join("..", "webapp", "test", "e2e", "basic.test.js"), join("webapp", "test", "e2e", "hash-nav.test.js")],
baseUrl: "http://localhost:8080/index.html"
baseUrl: "http://localhost:8080/index.html?isui5toolingTest=true",
wdi5: {
ignoreAutoWaitUrls: [".*/Categories.*"]
}
}

exports.config = merge(baseConfig, _config)
3 changes: 2 additions & 1 deletion examples/ui5-js-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"@wdio/mocha-framework": "^8",
"@wdio/spec-reporter": "^8",
"ui5-middleware-simpleproxy": "latest",
"wdio-ui5-service": "*"
"wdio-ui5-service": "*",
"@sap-ux/ui5-middleware-fe-mockserver": "latest"
},
"dependencies": {
"@wdio/sauce-service": "^8"
Expand Down
13 changes: 13 additions & 0 deletions examples/ui5-js-app/scripts/delayedMockServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const femiddleware = require("@sap-ux/ui5-middleware-fe-mockserver")

module.exports = async function middleware(middlewareConfig) {
const feMiddleware = await femiddleware(middlewareConfig)
return async (req, res, next) => {
if (req.originalUrl.startsWith("/V2") && req.originalUrl.includes("/Categories")) {
await new Promise((resolve) => setTimeout(resolve, 1000))
feMiddleware(req, res, next)
return
}
next()
}
}
16 changes: 16 additions & 0 deletions examples/ui5-js-app/ui5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ server:
configuration:
baseUri: "https://services.odata.org/V2"
strictSSL: false
- name: delayed-mockserver
beforeMiddleware: ui5-middleware-simpleproxy
configuration:
service:
urlBasePath: "/V2/Northwind/Northwind.svc"
name: ""
metadataXmlPath: "./webapp/localService/metadata.xml"
generateMockData: true
---
specVersion: "1.0"
metadata:
name: delayed-mockserver
kind: extension
type: server-middleware
middleware:
path: scripts/delayedMockServer.js
14 changes: 14 additions & 0 deletions examples/ui5-js-app/webapp/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ sap.ui.define(

// set the device model
this.setModel(models.createDeviceModel(), "device")

const url = new URL(location.href)
if (url.searchParams.get("isui5toolingTest")?.toLocaleLowerCase() === "true") {
const startXHR = () => {
this.getModel().read("/Categories", {
success: startXHR
})
}
startXHR()
const startFetch = () => {
fetch("/V2/Northwind/Northwind.svc/Categories").then(startFetch)
}
startFetch()
}
}
})
}
Expand Down
Loading

0 comments on commit 4f1255c

Please sign in to comment.