Skip to content

Commit a7fac9b

Browse files
authored
Fix e2e false positives (#1428)
* Added mechanisms for waiting for services to start * extract New Study Data from "open" response
1 parent 45dfff6 commit a7fac9b

File tree

4 files changed

+102
-11
lines changed

4 files changed

+102
-11
lines changed

tests/e2e/tutorials/mattward.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ async function runTutorial () {
2626

2727
await tutorial.registerIfNeeded();
2828
await tutorial.login();
29-
await tutorial.openTemplate(1000);
29+
const studyData = await tutorial.openTemplate(1000);
30+
const workbenchData = utils.extractWorkbenchData(studyData["data"]);
31+
await tutorial.waitForService(workbenchData["studyId"], workbenchData["nodeIds"][0]);
3032

31-
// Wait service to start and output files to be pushed
32-
await tutorial.waitFor(60000);
33+
// Wait for the output files to be pushed
34+
await tutorial.waitFor(30000);
3335

3436
// This study opens in fullscreen mode
3537
await tutorial.restoreIFrame();

tests/e2e/tutorials/tutorialBase.js

+28
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,46 @@ class TutorialBase {
9090
}
9191
}
9292

93+
async waitForOpen() {
94+
this.__responsesQueue.addResponseListener("open");
95+
let resp = null;
96+
try {
97+
resp = await this.__responsesQueue.waitUntilResponse("open");
98+
}
99+
catch(err) {
100+
console.error(this.__templateName, "could not be started", err);
101+
}
102+
return resp;
103+
}
104+
93105
async openTemplate(waitFor = 1000) {
94106
await utils.takeScreenshot(this.__page, this.__templateName + "_dashboardOpenFirstTemplate_before");
95107
this.__responsesQueue.addResponseListener("projects?from_template=");
108+
this.__responsesQueue.addResponseListener("open");
109+
let resp = null;
96110
try {
97111
await auto.dashboardOpenFirstTemplate(this.__page, this.__templateName);
98112
await this.__responsesQueue.waitUntilResponse("projects?from_template=");
113+
resp = await this.__responsesQueue.waitUntilResponse("open");
99114
}
100115
catch(err) {
101116
console.error(this.__templateName, "could not be started", err);
102117
}
103118
await this.__page.waitFor(waitFor);
104119
await utils.takeScreenshot(this.__page, this.__templateName + "_dashboardOpenFirstTemplate_after");
120+
return resp;
121+
}
122+
123+
async waitForService(studyId, nodeId) {
124+
this.__responsesQueue.addResponseServiceListener(studyId, nodeId);
125+
let resp = null;
126+
try {
127+
resp = await this.__responsesQueue.waitUntilServiceReady(studyId, nodeId);
128+
}
129+
catch(err) {
130+
console.error(this.__templateName, "could not be started", err);
131+
}
132+
return resp;
105133
}
106134

107135
async restoreIFrame() {

tests/e2e/utils/responsesQueue.js

+56-8
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ class ResponsesQueue {
88
this.__respReceivedQueue = {};
99
}
1010

11-
addResponseListener(url) {
11+
isRequestInQueue(url) {
12+
return this.__reqQueue.includes(url);
13+
}
14+
15+
isResponseInQueue(url) {
16+
return this.__respPendingQueue.includes(url);
17+
}
18+
19+
__addRequestListener(url) {
1220
const page = this.__page;
1321
const reqQueue = this.__reqQueue;
14-
const respPendingQueue = this.__respPendingQueue;
1522
reqQueue.push(url);
16-
respPendingQueue.push(url);
1723
console.log("-- Expected response added to queue", url);
1824
page.on("request", function callback(req) {
1925
if (req.url().includes(url)) {
@@ -25,6 +31,14 @@ class ResponsesQueue {
2531
}
2632
}
2733
});
34+
}
35+
36+
addResponseListener(url) {
37+
this.__addRequestListener(url);
38+
39+
const page = this.__page;
40+
const respPendingQueue = this.__respPendingQueue;
41+
respPendingQueue.push(url);
2842
const that = this;
2943
page.on("response", function callback(resp) {
3044
if (resp.url().includes(url)) {
@@ -52,12 +66,36 @@ class ResponsesQueue {
5266
});
5367
}
5468

55-
isRequestInQueue(url) {
56-
return this.__reqQueue.includes(url);
57-
}
69+
addResponseServiceListener(studyId, nodeId) {
70+
const url = "projects/" + studyId +"/nodes/" + nodeId;
71+
this.__addRequestListener(url);
5872

59-
isResponseInQueue(url) {
60-
return this.__respPendingQueue.includes(url);
73+
const page = this.__page;
74+
const respPendingQueue = this.__respPendingQueue;
75+
respPendingQueue.push(url);
76+
const that = this;
77+
page.on("response", function callback(resp) {
78+
if (resp.url().includes(url) && resp.status() === 200) {
79+
resp.json().then(data => {
80+
console.log((new Date).toUTCString(), "-- Queued services status response received", resp.url(), ":");
81+
const status = data["data"]["service_state"];
82+
console.log("Status:", status);
83+
const stopListening = [
84+
"running",
85+
"complete",
86+
"failed"
87+
];
88+
if (stopListening.includes(status)) {
89+
that.__respReceivedQueue[url] = data;
90+
page.removeListener("response", callback);
91+
const index = respPendingQueue.indexOf(url);
92+
if (index > -1) {
93+
respPendingQueue.splice(index, 1);
94+
}
95+
}
96+
});
97+
}
98+
});
6199
}
62100

63101
async waitUntilResponse(url, timeout = 10000) {
@@ -80,6 +118,16 @@ class ResponsesQueue {
80118
return resp;
81119
}
82120
}
121+
122+
async waitUntilServiceReady(studyId, nodeId, timeout = 30000) {
123+
const url = "projects/" + studyId +"/nodes/" + nodeId;
124+
const resp = await this.waitUntilResponse(url, timeout);
125+
const status = resp["data"]["service_state"];
126+
if (status !== "running") {
127+
throw("-- Failed starting service" + nodeId + ":" + status);
128+
}
129+
return resp;
130+
}
83131
}
84132

85133
module.exports = {

tests/e2e/utils/utils.js

+13
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ async function takeScreenshot(page, captureName) {
168168
})
169169
}
170170

171+
function extractWorkbenchData(data) {
172+
const workbenchData = {
173+
studyId: null,
174+
nodeIds: []
175+
};
176+
workbenchData.studyId = data["uuid"];
177+
if ("workbench" in data) {
178+
workbenchData.nodeIds = Object.keys(data["workbench"]);
179+
}
180+
return workbenchData;
181+
}
182+
171183
module.exports = {
172184
getUserAndPass,
173185
getDomain,
@@ -182,4 +194,5 @@ module.exports = {
182194
waitAndClick,
183195
sleep,
184196
takeScreenshot,
197+
extractWorkbenchData,
185198
}

0 commit comments

Comments
 (0)