Skip to content

Commit 75beb08

Browse files
committed
fix(cypress): enhance logging and improve API request timeouts in gitGateway and setup tasks
1 parent 5f5cbb1 commit 75beb08

File tree

5 files changed

+108
-44
lines changed

5 files changed

+108
-44
lines changed

cypress.config.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@ import { defineConfig } from 'cypress';
33
export default defineConfig({
44
projectId: '1c35bs',
55
retries: {
6-
runMode: 2, // Reduced from 4 - Cypress Cloud helps identify flaky tests
6+
runMode: 2,
77
openMode: 0,
88
},
99
e2e: {
1010
video: false,
11-
// We've imported your old cypress plugins here.
12-
// You may want to clean this up later by importing these.
1311
setupNodeEvents(on, config) {
1412
// eslint-disable-next-line @typescript-eslint/no-var-requires
1513
return require('./cypress/plugins/index.js')(on, config);

cypress/e2e/common/media_library.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ function publishPostWithImage(entry) {
8383
}
8484

8585
function closeMediaLibrary() {
86+
console.log('❌ Closing media library');
8687
cy.get('button[class*="CloseButton"]').click();
88+
console.log('❌ Media library closed');
8789
}
8890

8991
function switchToGridView() {

cypress/e2e/common/spec_utils.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ export const after = (taskResult, backend) => {
1616
export const beforeEach = (taskResult, backend) => {
1717
const spec = Cypress.mocha.getRunner().suite.ctx.currentTest.parent.title;
1818
const testName = Cypress.mocha.getRunner().suite.ctx.currentTest.title;
19+
20+
console.log(`🧪 Starting test: ${testName} (${backend})`);
21+
1922
cy.task('setupBackendTest', {
2023
backend,
2124
...taskResult.data,

cypress/plugins/gitGateway.js

Lines changed: 88 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const fetch = require('node-fetch');
2+
23
const {
34
transformRecordedData: transformGitHub,
45
setupGitHub,
@@ -33,39 +34,78 @@ function getEnvs() {
3334
const apiRoot = 'https://api.netlify.com/api/v1/';
3435

3536
async function get(netlifyApiToken, path) {
36-
const response = await fetch(`${apiRoot}${path}`, {
37-
headers: {
38-
'Content-Type': 'application/json',
39-
Authorization: `Bearer ${netlifyApiToken}`,
40-
},
41-
}).then(res => res.json());
42-
43-
return response;
37+
const controller = new AbortController();
38+
const timeout = setTimeout(() => controller.abort(), 10000); // 10 second timeout
39+
40+
try {
41+
const response = await fetch(`${apiRoot}${path}`, {
42+
signal: controller.signal,
43+
headers: {
44+
'Content-Type': 'application/json',
45+
Authorization: `Bearer ${netlifyApiToken}`,
46+
},
47+
}).then(res => res.json());
48+
clearTimeout(timeout);
49+
return response;
50+
} catch (error) {
51+
clearTimeout(timeout);
52+
if (error.name === 'AbortError') {
53+
console.error(`Netlify API GET timeout after 10s: ${path}`);
54+
throw new Error(`Netlify API GET request timeout: ${path}`);
55+
}
56+
throw error;
57+
}
4458
}
4559

4660
async function post(netlifyApiToken, path, payload) {
47-
const response = await fetch(`${apiRoot}${path}`, {
48-
method: 'POST',
49-
headers: {
50-
'Content-Type': 'application/json',
51-
Authorization: `Bearer ${netlifyApiToken}`,
52-
},
53-
...(payload ? { body: JSON.stringify(payload) } : {}),
54-
}).then(res => res.json());
55-
56-
return response;
61+
const controller = new AbortController();
62+
const timeout = setTimeout(() => controller.abort(), 10000); // 10 second timeout
63+
64+
try {
65+
const response = await fetch(`${apiRoot}${path}`, {
66+
signal: controller.signal,
67+
method: 'POST',
68+
headers: {
69+
'Content-Type': 'application/json',
70+
Authorization: `Bearer ${netlifyApiToken}`,
71+
},
72+
...(payload ? { body: JSON.stringify(payload) } : {}),
73+
}).then(res => res.json());
74+
clearTimeout(timeout);
75+
return response;
76+
} catch (error) {
77+
clearTimeout(timeout);
78+
if (error.name === 'AbortError') {
79+
console.error(`Netlify API POST timeout after 10s: ${path}`);
80+
throw new Error(`Netlify API POST request timeout: ${path}`);
81+
}
82+
throw error;
83+
}
5784
}
5885

5986
async function del(netlifyApiToken, path) {
60-
const response = await fetch(`${apiRoot}${path}`, {
61-
method: 'DELETE',
62-
headers: {
63-
'Content-Type': 'application/json',
64-
Authorization: `Bearer ${netlifyApiToken}`,
65-
},
66-
}).then(res => res.text());
67-
68-
return response;
87+
const controller = new AbortController();
88+
const timeout = setTimeout(() => controller.abort(), 10000); // 10 second timeout
89+
90+
try {
91+
const response = await fetch(`${apiRoot}${path}`, {
92+
signal: controller.signal,
93+
method: 'DELETE',
94+
headers: {
95+
'Content-Type': 'application/json',
96+
Authorization: `Bearer ${netlifyApiToken}`,
97+
},
98+
}).then(res => res.text());
99+
clearTimeout(timeout);
100+
return response;
101+
} catch (error) {
102+
clearTimeout(timeout);
103+
if (error.name === 'AbortError') {
104+
console.error(`Netlify API DELETE timeout after 10s: ${path}`);
105+
throw new Error(`Netlify API DELETE request timeout: ${path}`);
106+
}
107+
throw error;
108+
}
69109
}
70110

71111
async function createSite(netlifyApiToken, payload) {
@@ -90,16 +130,29 @@ async function enableLargeMedia(netlifyApiToken, siteId) {
90130
}
91131

92132
async function waitForDeploys(netlifyApiToken, siteId) {
93-
for (let i = 0; i < 10; i++) {
94-
const deploys = await get(netlifyApiToken, `sites/${siteId}/deploys`);
95-
if (deploys.some(deploy => deploy.state === 'ready')) {
96-
console.log('Deploy finished for site:', siteId);
97-
return;
133+
const maxRetries = 5; // Reduced from 10 to 5
134+
const retryDelayMs = 10 * 1000; // Reduced from 30s to 10s
135+
136+
for (let i = 0; i < maxRetries; i++) {
137+
try {
138+
const deploys = await get(netlifyApiToken, `sites/${siteId}/deploys`);
139+
140+
if (deploys && deploys.some(deploy => deploy.state === 'ready')) {
141+
return;
142+
}
143+
144+
if (i < maxRetries - 1) {
145+
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
146+
}
147+
} catch (error) {
148+
console.error(`Error checking deploy status: ${error.message}`);
149+
if (i < maxRetries - 1) {
150+
await new Promise(resolve => setTimeout(resolve, retryDelayMs));
151+
}
98152
}
99-
console.log('Waiting on deploy of site:', siteId);
100-
await new Promise(resolve => setTimeout(resolve, 30 * 1000));
101153
}
102-
console.log('Timed out waiting on deploy of site:', siteId);
154+
155+
console.error(`Timed out waiting on deploy of site: ${siteId}`);
103156
}
104157

105158
async function createUser(netlifyApiToken, siteUrl, email, password) {

cypress/plugins/index.js

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ module.exports = async (on, config) => {
4242
// `on` is used to hook into various events Cypress emits
4343
on('task', {
4444
async setupBackend({ backend, options }) {
45-
console.log('Preparing environment for backend', backend);
45+
console.log(`\n⏱️ [${new Date().toISOString()}] Preparing environment for backend ${backend}`);
46+
const setupStart = Date.now();
4647
await copyBackendFiles(backend);
4748

4849
let result = null;
@@ -51,7 +52,9 @@ module.exports = async (on, config) => {
5152
result = await setupGitHub(options);
5253
break;
5354
case 'git-gateway':
55+
console.log(`⏱️ Starting git-gateway setup: ${new Date().toISOString()}`);
5456
result = await setupGitGateway(options);
57+
console.log(`✅ Git-gateway setup completed in ${Date.now() - setupStart}ms`);
5558
break;
5659
case 'gitlab':
5760
result = await setupGitLab(options);
@@ -67,18 +70,22 @@ module.exports = async (on, config) => {
6770
break;
6871
}
6972

73+
console.log(`✅ Backend setup completed in ${Date.now() - setupStart}ms\n`);
7074
return result;
7175
},
7276
async teardownBackend(taskData) {
7377
const { backend } = taskData;
74-
console.log('Tearing down backend', backend);
78+
console.log(`\n⏱️ [${new Date().toISOString()}] Tearing down backend ${backend}`);
79+
const teardownStart = Date.now();
7580

7681
switch (backend) {
7782
case 'github':
7883
await teardownGitHub(taskData);
7984
break;
8085
case 'git-gateway':
86+
console.log(`⏱️ Starting git-gateway backend teardown`);
8187
await teardownGitGateway(taskData);
88+
console.log(`✅ Git-gateway backend teardown completed in ${Date.now() - teardownStart}ms`);
8289
break;
8390
case 'gitlab':
8491
await teardownGitLab(taskData);
@@ -94,18 +101,21 @@ module.exports = async (on, config) => {
94101
console.log('Restoring defaults');
95102
await copyBackendFiles('test');
96103

104+
console.log(`✅ Backend teardown completed in ${Date.now() - teardownStart}ms\n`);
97105
return null;
98106
},
99107
async setupBackendTest(taskData) {
100108
const { backend, testName } = taskData;
101-
console.log(`Setting up single test '${testName}' for backend`, backend);
109+
console.log(`Setting up test: ${testName} (${backend})`);
102110

103111
switch (backend) {
104112
case 'github':
105113
await setupGitHubTest(taskData);
106114
break;
107115
case 'git-gateway':
116+
const setupStart = Date.now();
108117
await setupGitGatewayTest(taskData);
118+
console.log(`git-gateway setup took ${Date.now() - setupStart}ms`);
109119
break;
110120
case 'gitlab':
111121
await setupGitLabTest(taskData);
@@ -121,9 +131,7 @@ module.exports = async (on, config) => {
121131
return null;
122132
},
123133
async teardownBackendTest(taskData) {
124-
const { backend, testName } = taskData;
125-
126-
console.log(`Tearing down single test '${testName}' for backend`, backend);
134+
const { backend } = taskData;
127135

128136
switch (backend) {
129137
case 'github':

0 commit comments

Comments
 (0)