Skip to content

Commit fa7ad0d

Browse files
Merge pull request #1751 from curvefi/chore/artifacts
feat: add cleanup functions for successful videos
2 parents b9e91f4 + a95589f commit fa7ad0d

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

tests/cypress/e2e/all/legal.cy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('Legal', () => {
4848
it('should use the first tab as default when the wrong tab is provided', () => {
4949
cy.visit('/lend/#/ethereum/legal?tab=dontexist')
5050
// Verify the first tab (Terms & Conditions) is selected
51-
cy.get("[data-testid='legal-page'] [role='tablist'] [role='tab']")
51+
cy.get("[data-testid='legal-page'] [role='tablist'] [role='tab']", LOAD_TIMEOUT)
5252
.first()
5353
.should('have.attr', 'aria-selected', 'true')
5454
.and('have.class', 'Mui-selected')
@@ -58,7 +58,7 @@ describe('Legal', () => {
5858
cy.visit('/lend/#/ethereum/legal?tab=disclaimers&subtab=dontexist')
5959

6060
// Verify the Disclaimers tab is selected and the lend subtab is selected
61-
cy.get("[data-testid='legal-page'] [role='tablist']")
61+
cy.get("[data-testid='legal-page'] [role='tablist']", LOAD_TIMEOUT)
6262
.contains("[role='tab']", 'LlamaLend')
6363
.should('have.attr', 'aria-selected', 'true')
6464
.and('have.class', 'Mui-selected')

tests/scripts/download-artifacts.ts

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { execFileSync, spawnSync, type ExecFileSyncOptionsWithStringEncoding } from 'child_process'
2-
import { mkdir } from 'fs/promises'
1+
import { execFileSync, type ExecFileSyncOptionsWithStringEncoding, spawnSync } from 'child_process'
2+
import { mkdir, readdir, unlink, rmdir } from 'fs/promises'
3+
import { dirname, join } from 'path'
34

45
const { BRANCH, WORKFLOW, DEST_DIR, REPOSITORY = 'curvefi/curve-frontend' } = process.env
56

@@ -53,10 +54,58 @@ const downloadArtifacts = (runId: string, dest: string) => {
5354
runStreaming('gh', ['run', 'download', runId, '--repo', REPOSITORY, '--dir', dest])
5455
}
5556

57+
/**
58+
* Check if a directory contains any .png files (indicating test failures).
59+
*/
60+
async function hasScreenshots(dir: string): Promise<boolean> {
61+
const entries = await readdir(dir, { withFileTypes: true }).catch((error: unknown) => {
62+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined // missing directory, so no screenshots
63+
throw error
64+
})
65+
if (!entries) return false // does not exist
66+
if (entries.length === 0) {
67+
console.info(`Removing empty screenshot directory: ${dir}`)
68+
await rmdir(dir)
69+
return false
70+
}
71+
for (const entry of entries) {
72+
const fullPath = join(dir, entry.name)
73+
if (entry.isDirectory()) {
74+
if (await hasScreenshots(fullPath)) {
75+
return true
76+
}
77+
} else if (entry.name.endsWith('.png')) {
78+
console.info(`Found screenshot file ${entry.name}`)
79+
return true
80+
}
81+
}
82+
return false
83+
}
84+
85+
/**
86+
* Recursively find and delete videos from successful tests (those without matching screenshots).
87+
*/
88+
async function cleanupSuccessfulTestVideos(dir: string): Promise<void> {
89+
const entries = await readdir(dir, { withFileTypes: true })
90+
91+
for (const entry of entries ?? []) {
92+
const fullPath = join(dir, entry.name)
93+
94+
if (entry.isDirectory()) {
95+
await cleanupSuccessfulTestVideos(fullPath)
96+
} else if (entry.name.endsWith('.mp4')) {
97+
// For a video file like "test.cy.ts.mp4", check if "test.cy.ts/" directory has screenshots
98+
const videoBaseName = entry.name.slice(0, -4) // Remove .mp4 extension
99+
const screenshotDir = join(dirname(fullPath), videoBaseName)
100+
if (!(await hasScreenshots(screenshotDir))) await unlink(fullPath)
101+
}
102+
}
103+
}
104+
56105
/**
57106
* Orchestrate download + extraction of the latest workflow artifacts for the current branch.
58107
*/
59-
async function downloadLatestArtifacts(): Promise<void> {
108+
async function downloadLatestArtifacts({ cleanup }: { cleanup: boolean }): Promise<void> {
60109
if (!hasCommand('gh')) {
61110
throw new Error('GitHub CLI (gh) is required but not installed.')
62111
}
@@ -78,9 +127,21 @@ async function downloadLatestArtifacts(): Promise<void> {
78127

79128
console.info(`Downloading artifacts for branch '${branch}' (workflow: ${workflow}, run: ${runId}) into '${dest}'...`)
80129
downloadArtifacts(runId, dest)
130+
131+
console.info('Cleaning up videos from successful tests...')
132+
await cleanupSuccessfulTestVideos(dest)
133+
console.info('Cleanup complete.')
81134
}
82135

83-
downloadLatestArtifacts().catch((error) => {
136+
/**
137+
* Simple usage:
138+
* node --experimental-strip-types scripts/download-artifacts.ts
139+
*
140+
* Custom usage:
141+
* BRANCH=feature/xyz WORKFLOW=ci.yaml DEST_DIR=tests/artifacts \
142+
* node --experimental-strip-types scripts/download-artifacts.ts --skip-cleanup
143+
*/
144+
downloadLatestArtifacts({ cleanup: !process.argv.includes('--skip-cleanup') }).catch((error) => {
84145
console.error(error instanceof Error ? error.message : error)
85146
process.exitCode = 1
86147
})

0 commit comments

Comments
 (0)