Skip to content

Commit e56b333

Browse files
authored
[patch] More test fixes (#148)
1 parent d998e60 commit e56b333

File tree

8 files changed

+126
-9
lines changed

8 files changed

+126
-9
lines changed

Diff for: package-lock.json

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
"debug": "4.3.5",
126126
"events": "3.3.0",
127127
"fast-glob": "3.3.2",
128+
"net": "^1.0.2",
128129
"uuid": "10.0.0",
129130
"uuid-by-string": "4.0.0",
130131
"ws": "8.17.1"

Diff for: src/plugins/server.ts

+69-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import PluginConfigOptions = Cypress.PluginConfigOptions;
22
import { RawData, WebSocketServer } from 'ws';
3+
import net from 'net';
34
import { ENV_WS, packageLog, wsPath } from '../common';
45
import Debug from 'debug';
56
import { AllureTasks, RequestTask } from '../plugins/allure-types';
@@ -18,11 +19,70 @@ const messageGot = (...args: unknown[]) => {
1819
logMessage(`${args}`);
1920
};
2021

21-
function getRandomPortNumber(): number {
22-
return 40000 + Math.round(Math.random() * 25000);
22+
const checkPortSync = (port: number, timeoutMs = 2000): boolean => {
23+
let isAvailable = true;
24+
let server: net.Server | null = null;
25+
let timeoutReached = false;
26+
const startTime = Date.now();
27+
28+
try {
29+
server = net.createServer();
30+
server.listen(port);
31+
32+
server.on('error', (err: NodeJS.ErrnoException) => {
33+
if (err.code === 'EADDRINUSE') {
34+
isAvailable = false;
35+
}
36+
});
37+
38+
const checkTimeout = () => {
39+
if (Date.now() - startTime >= timeoutMs) {
40+
timeoutReached = true;
41+
}
42+
};
43+
44+
const waitForListening = () => {
45+
if (!server?.listening && !timeoutReached) {
46+
process.nextTick(waitForListening); // Yield to event loop
47+
checkTimeout(); // Check if timeout has been reached
48+
}
49+
};
50+
51+
waitForListening();
52+
53+
if (timeoutReached) {
54+
throw new Error(`Timeout waiting for port ${port} to become available.`);
55+
}
56+
} catch (error) {
57+
isAvailable = false;
58+
} finally {
59+
if (server) {
60+
server.close();
61+
}
62+
}
63+
64+
return isAvailable;
65+
};
66+
67+
function retrieveRandomPortNumber(): number {
68+
const getRandomPort = () => 40000 + Math.round(Math.random() * 25000);
69+
let port = getRandomPort();
70+
71+
for (let i = 0; i < 30; i++) {
72+
const result = checkPortSync(port);
73+
74+
if (result) {
75+
return port;
76+
}
77+
port = getRandomPort();
78+
}
79+
80+
console.log(`${packageLog} could not find free port, will not report`);
81+
82+
return port;
2383
}
2484

25-
const socketLogic = (port: number, sockserver: WebSocketServer | undefined, tasks: AllureTasks) => {
85+
const socketLogic = (sockserver: WebSocketServer | undefined, tasks: AllureTasks) => {
2686
if (!sockserver) {
2787
log('Could not start reporting server');
2888

@@ -77,19 +137,21 @@ const socketLogic = (port: number, sockserver: WebSocketServer | undefined, task
77137
};
78138

79139
export const startReporterServer = (configOptions: PluginConfigOptions, tasks: AllureTasks, attempt = 0) => {
80-
const wsPort = getRandomPortNumber();
140+
const wsPort = retrieveRandomPortNumber();
81141

82-
const sockserver: WebSocketServer | undefined = new WebSocketServer({ port: wsPort, path: wsPath }, () => {
142+
let sockserver: WebSocketServer | undefined = new WebSocketServer({ port: wsPort, path: wsPath }, () => {
83143
configOptions.env[ENV_WS] = wsPort;
84144
const attemptMessage = attempt > 0 ? ` from ${attempt} attempt` : '';
85145
console.log(`${packageLog} running on ${wsPort} port${attemptMessage}`);
86-
socketLogic(wsPort, sockserver, tasks);
146+
socketLogic(sockserver, tasks);
87147
});
88148

89149
sockserver.on('error', err => {
90150
if (err.message.indexOf('address already in use') !== -1) {
91151
if (attempt < 30) {
92-
startReporterServer(configOptions, tasks, attempt + 1);
152+
process.nextTick(() => {
153+
sockserver = startReporterServer(configOptions, tasks, attempt + 1);
154+
});
93155
} else {
94156
console.error(`${packageLog} Could not find free port, will not report: ${err.message}`);
95157
}

Diff for: tests/cy-helper/utils.ts

+41
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ export const readWithRetry = (path: string, attempt = 0) => {
266266
export const createResTest2 = (
267267
specTexts: string[],
268268
envConfig?: Record<string, string | undefined>,
269+
shouldBeResults?: boolean,
269270
): {
270271
watch: string;
271272
specs: string[];
@@ -352,6 +353,31 @@ export const createResTest2 = (
352353
process.env.DEBUG = envConfig?.DEBUG ? 'cypress-allure*' : '';
353354
process.env.COVERAGE_REPORT_DIR = 'reports/coverage-cypress';
354355

356+
const checkFilesExist = retries => {
357+
return new Promise((resolve, reject) => {
358+
const attempt = remainingRetries => {
359+
if (!specs.every(p => existsSync(p))) {
360+
console.log(
361+
`Not all files were written: attempt ${retries - remainingRetries + 1}`,
362+
);
363+
364+
if (remainingRetries > 0) {
365+
return delay(1000)
366+
.then(() => attempt(remainingRetries - 1))
367+
.catch(reject);
368+
} else {
369+
return reject(
370+
new Error('Files are still missing after all retries'),
371+
);
372+
}
373+
}
374+
resolve(true);
375+
};
376+
377+
attempt(retries);
378+
});
379+
};
380+
355381
return cy
356382
.run({
357383
spec,
@@ -377,9 +403,24 @@ export const createResTest2 = (
377403

378404
return delay(1000);
379405
}
406+
})
407+
.then(() => {
408+
if (shouldBeResults) {
409+
return checkFilesExist(10);
410+
}
380411
});
381412
});
382413

414+
afterEach(() => {
415+
// to investigate issue with missing
416+
if (specs?.some(p => existsSync(p))) {
417+
specs.forEach(s => {
418+
const content = readFileSync(s);
419+
console.log(content.toString());
420+
});
421+
}
422+
});
423+
383424
return {
384425
watch: env.allureResultsWatchPath ?? storeResDir,
385426
specs: specs,

Diff for: tests/test-folder/common/utils.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ describe('utils', () => {
6363
it('delay', async () => {
6464
const started = Date.now();
6565
await delay(100);
66-
expect(Date.now() - started).toBeGreaterThanOrEqual(100);
66+
expect(Date.now() - started).toBeGreaterThanOrEqual(99); // sometime has 99 instead of 100
6767
});
6868

6969
it('messages should be dequeued in the same order as added', async () => {

Diff for: tests/test-folder/mocha-events/events/plugin-events-test-no-allure.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ describe('hello suite', () => {
2323
`,
2424
],
2525
{ allure: 'false' },
26+
false,
2627
);
2728
it('should be ok', () => {
2829
checkCyResults(res?.result?.res, {

Diff for: tests/test-folder/mocha-events/failures/test-retries/fail-one-test-before-each-retry.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('mocha events - check failures @oneInconsistency', () => {
1616
const res = createResTest2([
1717
`
1818
describe('hello suite', { retries: 1 }, () => {
19-
beforeEach(()=> {
19+
beforeEach(() => {
2020
cy.wrap(null).then(() => {
2121
throw new Error('Test FAIL on purpose');
2222
});

Diff for: tests/test-folder/mocha-events/interface/no-allure.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ describe('should be no results when allure:false', () => {
1414
`,
1515
],
1616
{ allure: 'false' },
17+
false,
1718
);
1819

1920
describe('check results', () => {

0 commit comments

Comments
 (0)