@@ -4,63 +4,87 @@ import path from 'path'
44
55const targetBranch = process . env . DRONE_TARGET_BRANCH || 'master'
66
7+ // paths that if changed will run all test suites
8+ const mandatoryPaths = [ 'tests/e2e/' , 'tests/drone/' , '.drone.star' , '.drone.env' , 'package.json' ]
9+
710// INFO: 1 and 2 elements are node and script name respectively
811const scriptDir = path . dirname ( process . argv [ 1 ] )
912const suitesToCheck = process . argv [ 2 ]
13+ . split ( ',' )
14+ . map ( ( suite ) => suite . trim ( ) )
15+ . filter ( ( suite ) => suite )
1016
11- const pacToTests = {
12- 'web-app-activities' : [ ] ,
13- 'web-app-admin-settings' : [ 'admin-settings' , 'keycloak' , 'smoke' , 'user-settings' ] ,
14- 'web-app-app-store' : [ 'app-store' ] ,
15- 'web-app-epub-reader' : [ ] ,
16- 'web-app-external' : [ 'app-provider' ] ,
17- 'web-app-files' : [
18- 'a11y' ,
19- 'admin-settings' ,
20- 'app-provider' ,
21- 'app-store' ,
22- 'file-action' ,
23- 'journeys' ,
24- 'keycloak' ,
25- 'navigation' ,
26- 'ocm' ,
27- 'oidc' ,
28- 'search' ,
29- 'shares' ,
30- 'smoke' ,
31- 'spaces' ,
32- 'user-settings'
33- ] ,
34- 'web-app-ocm' : [ 'ocm' ] ,
35- 'web-app-password-protected-folders' : [ 'file-action' ] ,
36- 'web-app-pdf-viewer' : [ ] ,
37- 'web-app-preview' : [ 'spaces' , 'shares' , 'file-action' , 'navigation' , 'ocm' ] ,
38- 'web-app-search' : [
39- 'a11y' ,
40- 'admin-settings' ,
41- 'app-provider' ,
42- 'app-store' ,
43- 'file-action' ,
44- 'journeys' ,
45- 'keycloak' ,
46- 'navigation' ,
47- 'ocm' ,
48- 'oidc' ,
49- 'search' ,
50- 'shares' ,
51- 'smoke' ,
52- 'spaces' ,
53- 'user-settings'
54- ] ,
55- 'web-app-text-editor' : [ 'keycloak' , 'oidc' ] ,
56- 'web-app-webfinger' : [ ]
57- }
17+ // list of test suites with dependent packages
18+ // Example:
19+ // {
20+ // 'web-app-ocm': ['ocm'],
21+ // 'web-app-search': ['search']
22+ // }
23+ const packageToTestSuiteMap = { }
5824
59- // get test suites
25+ /*
26+ --------------------
27+ web packages
28+ --------------------
29+ */
30+ const excludePackages = [ 'web-container' , 'web-test-helpers' ]
31+ // default packages that affect all test suites
32+ const defaultDependentPackages = [ 'design-system' , 'web-client' , 'web-runtime' , 'web-pkg' ]
33+ const packagesDir = `${ scriptDir } /../../packages`
34+ const allWebPackages = fs
35+ . readdirSync ( packagesDir )
36+ . filter (
37+ ( entry ) =>
38+ entry . startsWith ( 'web-' ) &&
39+ ! defaultDependentPackages . includes ( entry ) &&
40+ fs . statSync ( path . join ( packagesDir , entry ) ) . isDirectory ( ) &&
41+ ! excludePackages . includes ( entry )
42+ )
43+
44+ /*
45+ --------------------
46+ test suites
47+ --------------------
48+ */
6049const testSuitesDir = `${ scriptDir } /../e2e/cucumber/features`
61- const testSuites = fs
62- . readdirSync ( testSuitesDir )
63- . filter ( ( entry ) => fs . statSync ( path . join ( testSuitesDir , entry ) ) . isDirectory ( ) )
50+ const testSuites = fs . readdirSync ( testSuitesDir ) . filter ( ( entry ) => {
51+ if ( ! fs . statSync ( path . join ( testSuitesDir , entry ) ) . isDirectory ( ) ) {
52+ return false
53+ }
54+ const webPackagesFile = path . join ( testSuitesDir , entry , 'web-packages.txt' )
55+ if ( fs . existsSync ( webPackagesFile ) ) {
56+ const content = fs . readFileSync ( webPackagesFile , 'utf-8' )
57+ const depPackages = content . split ( '\n' ) . filter ( ( line ) => line && line . startsWith ( 'web-' ) )
58+ if ( depPackages . length ) {
59+ mapDependentPackagesToTestSuite ( entry , depPackages )
60+ return
61+ }
62+ }
63+ // make all packages as dependent
64+ mapDependentPackagesToTestSuite ( entry , allWebPackages )
65+ return
66+ } )
67+
68+ function mapDependentPackagesToTestSuite ( testSuite , depPackages ) {
69+ depPackages . forEach ( ( pkg ) => {
70+ if ( ! fs . existsSync ( path . join ( packagesDir , pkg ) ) ) {
71+ throw new Error (
72+ `Package "${ pkg } " listed as dependent for test suite "${ testSuite } " does not exist.\nPath: ${ path . join ( packagesDir , pkg ) } `
73+ )
74+ }
75+
76+ if ( ! ( pkg in packageToTestSuiteMap ) ) {
77+ packageToTestSuiteMap [ pkg ] = [ ]
78+ }
79+ ! packageToTestSuiteMap [ pkg ] . includes ( testSuite ) && packageToTestSuiteMap [ pkg ] . push ( testSuite )
80+ } )
81+ defaultDependentPackages . forEach ( ( pkg ) => {
82+ if ( ! ( pkg in packageToTestSuiteMap ) ) {
83+ packageToTestSuiteMap [ pkg ] = [ ]
84+ }
85+ ! packageToTestSuiteMap [ pkg ] . includes ( testSuite ) && packageToTestSuiteMap [ pkg ] . push ( testSuite )
86+ } )
87+ }
6488
6589function getChangedFiles ( ) {
6690 const changedFiles = execSync ( `git diff --name-only origin/${ targetBranch } HEAD` ) . toString ( )
@@ -72,7 +96,7 @@ function getPackageFromFile(file) {
7296 if ( ! file . startsWith ( 'packages/' ) ) {
7397 return
7498 }
75- const packages = Object . keys ( pacToTests )
99+ const packages = Object . keys ( packageToTestSuiteMap )
76100 for ( const pkg of packages ) {
77101 if ( file . startsWith ( `packages/${ pkg } ` ) ) {
78102 return pkg
@@ -83,24 +107,21 @@ function getPackageFromFile(file) {
83107function getAffectedTestSuites ( changedFiles ) {
84108 const affectedSuites = new Set ( )
85109 for ( const file of changedFiles ) {
86- if (
87- file . startsWith ( 'tests/e2e/' ) ||
88- file . startsWith ( 'tests/drone/' ) ||
89- file === '.drone.star' ||
90- file === 'package.json'
91- ) {
110+ if ( mandatoryPaths . some ( ( mandatoryPath ) => file . startsWith ( mandatoryPath ) ) ) {
92111 // run all test suites
93112 return testSuites
94113 }
95114 const packageName = getPackageFromFile ( file )
96- if ( packageName && packageName in pacToTests ) {
97- pacToTests [ packageName ] . forEach ( ( suite ) => affectedSuites . add ( suite ) )
115+ if ( packageName && packageName in packageToTestSuiteMap ) {
116+ packageToTestSuiteMap [ packageName ] . forEach ( ( suite ) => affectedSuites . add ( suite ) )
98117 }
99118 }
100119 return Array . from ( affectedSuites )
101120}
102121
103122function createSuitesToRunEnvFile ( suites = [ ] ) {
123+ console . log ( '[INFO] Provided test suites/features:\n - ' + suitesToCheck . join ( '\n - ' ) )
124+ console . log ( '[INFO] Test suites/features to run:\n - ' + suites . join ( '\n - ' ) )
104125 const envContent = [ 'TEST_SUITES' , suites . join ( ',' ) ]
105126 if ( suites [ 0 ] . startsWith ( 'cucumber/' ) ) {
106127 envContent [ 0 ] = [ 'FEATURE_FILES' ]
@@ -117,11 +138,11 @@ function main() {
117138 }
118139 const affectedTestSuites = getAffectedTestSuites ( changedFiles )
119140 if ( affectedTestSuites . length === 0 ) {
120- console . log ( '[INFO] No affected test suites to run.' )
141+ console . log ( '[INFO] No affected test suites/features to run.' )
121142 process . exit ( 78 ) // Skip the pipeline
122143 }
123- if ( suitesToCheck ) {
124- const suitesToRun = suitesToCheck . split ( ',' ) . filter ( ( suite ) => {
144+ if ( suitesToCheck . length ) {
145+ const suitesToRun = suitesToCheck . filter ( ( suite ) => {
125146 suite = suite . trim ( )
126147 if ( suite . startsWith ( 'cucumber/' ) ) {
127148 suite = suite . replace ( 'cucumber/features/' , '' ) . split ( '/' ) . shift ( )
@@ -130,8 +151,8 @@ function main() {
130151 } )
131152 if ( suitesToRun . length === 0 ) {
132153 console . log (
133- '[INFO] The following test suites are not affected and will be skipped:' ,
134- suitesToCheck . split ( ',' ) . join ( '\n' )
154+ '[INFO] The following test suites/features are not affected and will be skipped:\n - ' ,
155+ suitesToCheck . join ( '\n - ' )
135156 )
136157 process . exit ( 78 ) // Skip the pipeline
137158 }
0 commit comments