1- const fs = require ( 'fs' ) ;
2-
3- // Helper function to extract all tests from a suite recursively
4- function extractTestsFromSuite ( suite , parentTitle = '' ) {
5- let tests = [ ] ;
6- const fullSuiteTitle = parentTitle ? `${ parentTitle } > ${ suite . title } ` : suite . title ;
7-
8- if ( suite . specs ) {
9- tests . push ( ...suite . specs . map ( spec => {
10- const isSkipped = spec . tests && spec . tests [ 0 ] &&
11- ( spec . tests [ 0 ] . annotations ?. some ( a => a . type === 'skip' ) ||
12- spec . tests [ 0 ] . status === 'skipped' ) ;
13-
14- return {
15- title : spec . title ,
16- fullTitle : `${ fullSuiteTitle } > ${ spec . title } ` ,
17- status : isSkipped ? 'skipped' : ( spec . ok ? 'passed' : 'failed' ) ,
18- file : suite . file ,
19- skipped : isSkipped
20- } ;
21- } ) ) ;
22- }
1+ const { compareTests } = require ( './utils/test' ) ;
2+ const { generateTestChangesSummary } = require ( './utils/format' ) ;
3+ const { generateBundleSizeSection, getBundleInfo } = require ( './utils/bundle' ) ;
4+ const { readTestResults, getTestStatus } = require ( './utils/results' ) ;
5+
6+ /**
7+ * Main function to update PR description with test results and bundle size information
8+ * @param {Object } github - GitHub API object
9+ * @param {Object } context - GitHub Actions context
10+ */
11+ async function updatePRDescription ( github , context ) {
12+ // Read test results
13+ const currentResults = readTestResults ( 'playwright-artifacts/test-results.json' ) ;
14+ const mainResults = readTestResults ( 'gh-pages/main/test-results.json' ) ;
2315
24- // Recursively process nested suites
25- if ( suite . suites ) {
26- suite . suites . forEach ( nestedSuite => {
27- tests . push ( ...extractTestsFromSuite ( nestedSuite , fullSuiteTitle ) ) ;
28- } ) ;
29- }
16+ // Compare tests
17+ const testComparison = compareTests ( currentResults . tests , mainResults . tests ) ;
3018
31- return tests ;
32- }
33-
34- function formatSize ( size ) {
35- if ( size >= 1024 ) {
36- return `${ ( size / ( 1024 * 1024 ) ) . toFixed ( 2 ) } MB` ;
37- }
38- return `${ ( size / 1024 ) . toFixed ( 2 ) } KB` ;
39- }
40-
41- async function updatePRDescription ( github , context ) {
42- const testResultsPath = 'playwright-artifacts/test-results.json' ;
43- const mainTestResultsPath = 'gh-pages/main/test-results.json' ;
44- let testResults ;
45- let mainTestResults ;
46- let testComparison = {
47- new : [ ] ,
48- skipped : [ ] ,
49- deleted : [ ]
50- } ;
51-
52- // Read current PR test results
53- if ( fs . existsSync ( testResultsPath ) ) {
54- const rawData = fs . readFileSync ( testResultsPath ) ;
55- const data = JSON . parse ( rawData ) ;
56- const allTests = data . suites . flatMap ( suite => extractTestsFromSuite ( suite ) ) ;
57-
58- testResults = {
59- total : data . stats . expected + data . stats . unexpected + data . stats . flaky + data . stats . skipped ,
60- passed : data . stats . expected ,
61- failed : data . stats . unexpected ,
62- flaky : data . stats . flaky ,
63- skipped : data . stats . skipped ,
64- tests : allTests
65- } ;
66- } else {
67- console . log ( 'Test results file not found' ) ;
68- testResults = { total : 0 , passed : 0 , failed : 0 , flaky : 0 , skipped : 0 , tests : [ ] } ;
69- }
70-
71- // Read main branch test results
72- if ( fs . existsSync ( mainTestResultsPath ) ) {
73- const rawData = fs . readFileSync ( mainTestResultsPath ) ;
74- const data = JSON . parse ( rawData ) ;
75- const allTests = data . suites . flatMap ( suite => extractTestsFromSuite ( suite ) ) ;
76- mainTestResults = { tests : allTests } ;
77-
78- // Compare tests
79- const currentTests = new Map ( testResults . tests . map ( t => [ t . fullTitle , t ] ) ) ;
80- const mainTests = new Map ( mainTestResults . tests . map ( t => [ t . fullTitle , t ] ) ) ;
81-
82- // Find new tests
83- for ( const [ fullTitle , test ] of currentTests ) {
84- if ( ! mainTests . has ( fullTitle ) ) {
85- testComparison . new . push ( `${ test . title } (${ test . file } )` ) ;
86- }
87- }
88-
89- // Find deleted tests
90- for ( const [ fullTitle , test ] of mainTests ) {
91- if ( ! currentTests . has ( fullTitle ) ) {
92- testComparison . deleted . push ( `${ test . title } (${ test . file } )` ) ;
93- }
94- }
95-
96- // Find skipped tests (both newly skipped and already skipped)
97- testComparison . skipped = testResults . tests
98- . filter ( t => t . skipped )
99- . map ( test => `${ test . title } (${ test . file } )` ) ;
100-
101- testComparison . skipped = Array . from ( new Set ( testComparison . skipped ) ) ;
102- } else {
103- console . log ( 'Main branch test results file not found' ) ;
104- mainTestResults = { tests : [ ] } ;
105- }
106-
19+ // Get test status and report URL
20+ const { status, statusColor } = getTestStatus ( currentResults ) ;
10721 const reportUrl = `https://${ context . repo . owner } .github.io/${ context . repo . repo } /${ context . issue . number } /` ;
108- const status = testResults . failed > 0 ? '❌ FAILED' : ( testResults . flaky > 0 ? '⚠️ FLAKY' : '✅ PASSED' ) ;
109- const statusColor = testResults . failed > 0 ? 'red' : ( testResults . flaky > 0 ? 'orange' : 'green' ) ;
110-
111- // Get bundle size information from environment variables
112- const currentSize = parseInt ( process . env . CURRENT_SIZE || '0' ) ;
113- const mainSize = parseInt ( process . env . MAIN_SIZE || '0' ) ;
114- const diff = parseInt ( process . env . SIZE_DIFF || '0' ) ;
115- const percent = process . env . SIZE_PERCENT || 'N/A' ;
11622
117- const bundleStatus = percent === 'N/A' ? '⚠️' :
118- parseFloat ( percent ) > 0 ? '🔺' :
119- parseFloat ( percent ) < 0 ? '🔽' : '✅' ;
120-
121- // Generate test changes summary based on actual changes
122- let testChangesSummary = '😟 No changes in tests. 😕' ;
123- if ( testComparison . new . length > 0 || testComparison . deleted . length > 0 || testComparison . skipped . length > 0 ) {
124- testChangesSummary = `
125- <details>
126- <summary>Test Changes Summary ${ testComparison . new . length > 0 ? `✨${ testComparison . new . length } ` : '' } ${ testComparison . skipped . length > 0 ? `⏭️${ testComparison . skipped . length } ` : '' } ${ testComparison . deleted . length > 0 ? `🗑️${ testComparison . deleted . length } ` : '' } </summary>
127-
128- ${ testComparison . new . length > 0 ? `#### ✨ New Tests (${ testComparison . new . length } )
129- ${ testComparison . new . map ( ( test , i ) => `${ i + 1 } . ${ test } ` ) . join ( '\n' ) }
130-
131- ` : '' } ${ testComparison . skipped . length > 0 ? `#### ⏭️ Skipped Tests (${ testComparison . skipped . length } )
132- ${ testComparison . skipped . map ( ( test , i ) => `${ i + 1 } . ${ test } ` ) . join ( '\n' ) }
133-
134- ` : '' } ${ testComparison . deleted . length > 0 ? `#### 🗑️ Deleted Tests (${ testComparison . deleted . length } )
135- ${ testComparison . deleted . map ( ( test , i ) => `${ i + 1 } . ${ test } ` ) . join ( '\n' ) } ` : '' }
136- </details>` ;
137- }
23+ // Get bundle size information
24+ const bundleInfo = getBundleInfo ( ) ;
13825
26+ // Generate the CI section content
13927 const ciSection = `## CI Results
14028
14129 ### Test Status: <span style="color: ${ statusColor } ;">${ status } </span>
14230 📊 [Full Report](${ reportUrl } )
14331
14432 | Total | Passed | Failed | Flaky | Skipped |
14533 |:-----:|:------:|:------:|:-----:|:-------:|
146- | ${ testResults . total } | ${ testResults . passed } | ${ testResults . failed } | ${ testResults . flaky } | ${ testResults . skipped } |
147-
148- ${ testChangesSummary }
34+ | ${ currentResults . total } | ${ currentResults . passed } | ${ currentResults . failed } | ${ currentResults . flaky } | ${ currentResults . skipped } |
14935
150- ### Bundle Size: ${ bundleStatus }
151- Current: ${ formatSize ( currentSize ) } | Main: ${ formatSize ( mainSize ) }
152- Diff: ${ diff > 0 ? '+' : '' } ${ formatSize ( Math . abs ( diff ) ) } (${ percent === 'N/A' ? 'N/A' : `${ percent } %` } )
36+ ${ generateTestChangesSummary ( testComparison ) }
15337
154- ${
155- percent === 'N/A' ? '⚠️ Unable to calculate change.' :
156- parseFloat ( percent ) > 0 ? '⚠️ Bundle size increased. Please review.' :
157- parseFloat ( percent ) < 0 ? '✅ Bundle size decreased.' : '✅ Bundle size unchanged.'
158- }
38+ ${ generateBundleSizeSection ( bundleInfo ) }
15939
16040 <details>
16141 <summary>ℹ️ CI Information</summary>
@@ -166,6 +46,7 @@ async function updatePRDescription(github, context) {
16646 - 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
16747 </details>` ;
16848
49+ // Update PR description
16950 const { data : pullRequest } = await github . rest . pulls . get ( {
17051 owner : context . repo . owner ,
17152 repo : context . repo . repo ,
@@ -175,12 +56,9 @@ async function updatePRDescription(github, context) {
17556 const currentBody = pullRequest . body || '' ;
17657 const ciSectionRegex = / # # C I R e s u l t s [ \s \S ] * ?(? = \n # # (? ! C I R e s u l t s ) | $ ) / ;
17758
178- let newBody = currentBody ;
179- if ( ciSectionRegex . test ( newBody ) ) {
180- newBody = newBody . replace ( ciSectionRegex , ciSection ) ;
181- } else {
182- newBody += '\n\n' + ciSection ;
183- }
59+ const newBody = ciSectionRegex . test ( currentBody )
60+ ? currentBody . replace ( ciSectionRegex , ciSection )
61+ : currentBody + '\n\n' + ciSection ;
18462
18563 await github . rest . pulls . update ( {
18664 owner : context . repo . owner ,
0 commit comments