Skip to content

Commit 1d14640

Browse files
authored
Merge pull request #291 from HRanjan-11/CYP-905
added failed test retry
2 parents cf70e02 + b4fafb2 commit 1d14640

File tree

6 files changed

+191
-33
lines changed

6 files changed

+191
-33
lines changed

commands/generate_reports.js

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ function download_artefact(
1717
) {
1818
return new Promise(function (resolve, reject) {
1919
let response_code;
20+
let resp;
2021
if (!fs.existsSync(file_path)) {
2122
fs.mkdirSync(file_path, { recursive: true });
2223
}
@@ -44,6 +45,7 @@ function download_artefact(
4445
reject(err);
4546
}
4647
response_code = res.statusCode;
48+
resp = res
4749
}).pipe(
4850
fs
4951
.createWriteStream(file_path, {
@@ -65,6 +67,11 @@ function download_artefact(
6567
});
6668
} else {
6769
fs.unlinkSync(file_path);
70+
if (resp.body != null) {
71+
const responseObject = JSON.parse(resp.body);
72+
const dataValue = responseObject.data;
73+
reject("Could not download artefacts for test id " + test_id + " with reason " + dataValue);
74+
}
6875
reject("Could not download artefacts for test id " + test_id);
6976
}
7077
})
@@ -73,7 +80,7 @@ function download_artefact(
7380
}
7481

7582
function generate_report(args) {
76-
return new Promise(function (resolve, reject) {
83+
return new Promise(async function (resolve, reject) {
7784
var username = "";
7885
var access_key = "";
7986

@@ -96,7 +103,6 @@ function generate_report(args) {
96103
} else {
97104
reject("Access Key not provided");
98105
}
99-
100106
//Check for session id
101107
if (
102108
!("session_id" in args) ||
@@ -123,7 +129,6 @@ function generate_report(args) {
123129
);
124130
}
125131
}
126-
127132
//set working enviornment
128133
var env = "prod";
129134
if ("env" in args) {
@@ -184,8 +189,10 @@ function generate_report(args) {
184189
fs.mkdirSync(directory, { recursive: true });
185190
console.log("Directory created ", directory);
186191
}
192+
const downloadPromises = [];
193+
187194
for (i = 0; i < build_info["data"].length; i++) {
188-
download_artefact(
195+
const downloadPromise = download_artefact(
189196
username,
190197
access_key,
191198
env,
@@ -198,26 +205,34 @@ function generate_report(args) {
198205
),
199206
build_payload["run_settings"]["reject_unauthorized"]
200207
)
201-
.then(function (resp) {
202-
//Files downloaded
203-
console.log(resp);
204-
})
205-
.catch(function (err) {
206-
console.log(err);
207-
});
208+
downloadPromises.push(downloadPromise)
208209
}
209-
resolve("Done");
210+
211+
Promise.allSettled(downloadPromises)
212+
.then((results) => {
213+
// results is an array of objects
214+
for (const result of results) {
215+
if (result.status == 'fulfilled') {
216+
console.log(result.value);
217+
} else if (result.status == 'rejected') {
218+
console.log(result.reason);
219+
}
220+
}
221+
resolve("Done");
222+
})
223+
.catch((error) => {
224+
// This catch block will not be executed
225+
console.log(error);
226+
resolve("Done");
227+
});
228+
210229
})
211230
.catch(function (err) {
212231
console.log("Error occured while getting the build response", err);
213232
});
214233
});
215234
}
216235

217-
module.exports = function (args) {
218-
generate_report(args)
219-
.then(function (resp) {})
220-
.catch(function (err) {
221-
console.log("ERR:", err);
222-
});
236+
module.exports = {
237+
generate_report:generate_report
223238
};

commands/utils/batch/batch_runner.js

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const { del } = require("request");
1212
const { delete_archive } = require("../archive.js");
1313
const poller = require("../poller/poller.js");
1414
const builds = require("../poller/build");
15+
const batcher = require("./batcher.js");
16+
const reports = require("../../../commands/generate_reports.js");
17+
const { fail } = require("yargs");
1518

1619
var batchCounter = 0;
1720
var totalBatches = 0;
@@ -91,6 +94,7 @@ async function run(lt_config, batches, env) {
9194
.archive_project(lt_config)
9295
.then(function (file_obj) {
9396
project_file = file_obj["name"];
97+
lt_config["run_settings"]["project_file"] = project_file;
9498
//upload the project and get the project link
9599
uploader
96100
.upload_zip(lt_config, file_obj["name"], "project", env)
@@ -121,14 +125,15 @@ async function run(lt_config, batches, env) {
121125
access_key: lt_config["lambdatest_auth"]["access_key"],
122126
type: "cypress"
123127
});
124-
125128
run_test(
126129
payload,
127130
env,
128131
lt_config.run_settings.reject_unauthorized
129132
)
130133
.then(function (session_id) {
131-
delete_archive(project_file);
134+
if (lt_config["run_settings"]["retry_failed"] == false ) {
135+
delete_archive(project_file);
136+
}
132137
delete_archive(file_obj["name"]);
133138
//listen to control+c signal and stop tests
134139
process.on("SIGINT", async () => {
@@ -148,13 +153,48 @@ async function run(lt_config, batches, env) {
148153
});
149154
if (
150155
lt_config["run_settings"]["sync"] == true ||
151-
(lt_config["tunnel_settings"]["tunnel"] && lt_config["tunnel_settings"]["autostart"])
156+
(lt_config["tunnel_settings"]["tunnel"] && lt_config["tunnel_settings"]["autostart"]) || (lt_config["run_settings"]["retry_failed"] == true )
152157
) {
153158
console.log("Waiting for build to finish...");
154-
poller
155-
.poll_build(lt_config, session_id, env)
156-
.then(function (exit_code) {
157-
resolve(exit_code);
159+
poller.update_status(true);
160+
poller.poll_build(lt_config, session_id, env)
161+
.then( function (result) {
162+
const { exit_code, build_info } = result;
163+
if (lt_config["run_settings"]["retry_failed"] == true && build_info != null ) {
164+
let failed_tests = [];
165+
for (i = 0; i < build_info["data"].length; i++) {
166+
if (build_info["data"][i]["status_ind"] == "failed" ) {
167+
failed_tests.push(build_info["data"][i]["path"]);
168+
}
169+
}
170+
if (failed_tests.length > 0) {
171+
console.log("retrying these failed tests "+ failed_tests)
172+
lt_config["run_settings"]["specs"]=failed_tests;
173+
batcher
174+
.make_batches(lt_config)
175+
.then(function (batches) {
176+
retry_run(lt_config, batches, env)
177+
.then(function (exit_code) {
178+
if (exit_code) {
179+
console.log("retried failed tests ended with exit code " + exit_code);
180+
}
181+
resolve(exit_code);
182+
})
183+
.catch(function (error) {
184+
console.log(error);
185+
resolve(1);
186+
});
187+
})
188+
.catch(function (err) {
189+
console.log(err);
190+
resolve(1);
191+
});
192+
} else {
193+
resolve(exit_code);
194+
}
195+
} else {
196+
resolve(exit_code);
197+
}
158198
})
159199
.catch(function (err) {
160200
console.log(
@@ -193,6 +233,92 @@ async function run(lt_config, batches, env) {
193233
});
194234
}
195235

236+
async function retry_run(lt_config, batches, env) {
237+
totalBatches = batches.length;
238+
return new Promise(function (resolve, reject) {
239+
lt_config["test_suite"] = batches[0];
240+
archive
241+
.archive_batch(lt_config, batches[0], env)
242+
.then(async function (file_obj) {
243+
uploader
244+
.upload_zip(lt_config, file_obj["name"], "tests", env)
245+
.then(async function (resp) {
246+
247+
var payload = JSON.stringify({
248+
payload: {
249+
test_file: resp["value"]["message"].split("?")[0],
250+
},
251+
username: lt_config["lambdatest_auth"]["username"],
252+
access_key: lt_config["lambdatest_auth"]["access_key"],
253+
type: "cypress"
254+
});
255+
256+
run_test(
257+
payload,
258+
env,
259+
lt_config.run_settings.reject_unauthorized
260+
).then(function (session_id) {
261+
262+
delete_archive(lt_config["run_settings"]["project_file"]);
263+
delete_archive(file_obj["name"]);
264+
265+
process.on("SIGINT", async () => {
266+
try {
267+
console.log(
268+
"Retry - Control+c signal received.\nTrying to Terminate the processes"
269+
);
270+
await builds.stop_cypress_session(
271+
lt_config,
272+
session_id,
273+
env
274+
);
275+
resolve(0);
276+
} catch (e) {
277+
console.log("Retry - Could not exit process. Try Again!!!");
278+
}
279+
});
280+
if (
281+
lt_config["run_settings"]["sync"] == true ||
282+
(lt_config["tunnel_settings"]["tunnel"] && lt_config["tunnel_settings"]["autostart"])
283+
) {
284+
console.log("Retry - Waiting for build to finish...");
285+
poller.update_status(true);
286+
poller.poll_build(lt_config, session_id, env)
287+
.then(function (result) {
288+
const { exit_code, build_json } = result;
289+
resolve(exit_code);
290+
})
291+
.catch(function (err) {
292+
console.log(
293+
"Retry - Some error occured in getting build updates",
294+
err.message
295+
);
296+
});
297+
} else {
298+
resolve(0);
299+
}
300+
301+
})
302+
.catch(function (err) {
303+
console.log("Retry - Error occured while creating tests", err);
304+
});
305+
306+
307+
})
308+
.catch(function (err) {
309+
console.log("Retry - Not able to archive the batch of test files", err);
310+
});
311+
312+
})
313+
.catch(function (err) {
314+
console.log("Retry - Unable to archive the project");
315+
console.log(err);
316+
reject(err);
317+
});
318+
});
319+
}
320+
196321
module.exports = {
197322
run_batches: run,
323+
run_batches_retry: retry_run,
198324
};

commands/utils/poller/build_stats.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ function get_build_info(lt_config, session_id, env, update_status, callback) {
106106
) {
107107
get_build_info_count = get_build_info_count + 1;
108108
if (get_build_info_count > 4) {
109+
get_build_info_count = 0;
109110
update_status(false);
110111
return callback(null, JSON.parse(body));
111112
}

commands/utils/poller/poller.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ function poll_build(lt_config, session_id, env) {
2323
if (err == null) {
2424
build_stats
2525
.get_completed_build_info(lt_config, session_id, env)
26-
.then(function (build_info) {
26+
.then(async function (build_info) {
2727
if (!build_info || build_info.data == null) {
2828
console.log("Build info not found");
29-
resolve(1);
29+
resolve({exit_code:1, build_info:build_info});
3030
return;
3131
}
3232
let stats = {};
@@ -55,24 +55,25 @@ function poll_build(lt_config, session_id, env) {
5555
reject_unauthorized:
5656
lt_config.run_settings.reject_unauthorized,
5757
};
58-
reports(args);
58+
59+
await reports.generate_report(args)
5960
}
6061
if (
6162
Object.keys(stats).length == 1 &&
6263
(Object.keys(stats).includes("completed") ||
6364
Object.keys(stats).includes("passed"))
6465
) {
65-
resolve(0);
66+
resolve({exit_code:0, build_info:build_info});
6667
} else {
67-
resolve(1);
68+
resolve({exit_code:1, build_info:build_info});
6869
}
6970
})
7071
.catch(function (err) {
7172
console.log("Error", err);
7273
});
7374
} else {
7475
console.log(err);
75-
resolve(1);
76+
resolve({exit_code:1, build_info:null});
7677
}
7778
}
7879
);

commands/utils/set_args.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,16 @@ function sync_args_from_cmd(args) {
387387
lt_config["run_settings"]["network_sse"] = false;
388388
}
389389

390+
if ("retry_failed" in args) {
391+
if (args["retry_failed"] == "true") {
392+
lt_config.run_settings.retry_failed = true;
393+
} else {
394+
lt_config.run_settings.retry_failed = false;
395+
}
396+
} else if (lt_config["run_settings"]["retry_failed"] && !lt_config["run_settings"]["retry_failed"]) {
397+
lt_config["run_settings"]["retry_failed"] = false;
398+
}
399+
390400
if ("headless" in args) {
391401
lt_config["run_settings"]["headless"] = args["headless"];
392402
} else if (!lt_config["run_settings"]["headless"]) {

index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ const argv = require("yargs")
213213
describe: "show command logs on dashboard.",
214214
type: "string",
215215
})
216+
.option("ret_fail", {
217+
alias: "retry_failed",
218+
describe: "run failed tests in a new build.",
219+
type: "bool",
220+
})
216221
.option("net_http2", {
217222
alias: "network_http2",
218223
describe: "Capture Http2 Network logs",
@@ -227,7 +232,7 @@ const argv = require("yargs")
227232
alias: "network_sse",
228233
describe: "Bypass sse events calls for Network logs",
229234
type: "bool",
230-
});;
235+
});
231236
},
232237
function (argv) {
233238
require("./commands/run")(argv);
@@ -344,7 +349,7 @@ const argv = require("yargs")
344349
});
345350
},
346351
function (argv) {
347-
require("./commands/generate_reports")(argv);
352+
require("./commands/generate_reports").generate_report(argv);
348353
}
349354
)
350355
.help().argv;

0 commit comments

Comments
 (0)