| // Copyright 2026 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import fs from 'node:fs'; | |
| import path from 'node:path'; | |
| import {parseExpectations, serializeExpectations} from '../test/conductor/test_expectations_parser.js'; | |
| import {getFlakyClusters} from './fetch_luci_test_clusters.ts'; | |
| async function main(): Promise<void> { | |
| const expectationsPath = path.join(import.meta.dirname, '..', 'test', 'TestExpectations'); | |
| const content = fs.readFileSync(expectationsPath, 'utf-8'); | |
| const expectations = parseExpectations(content); | |
| console.log('Fetching LUCI Analysis clusters for the last 7 days...'); | |
| const clusters = await getFlakyClusters(7); | |
| let modified = false; | |
| const newExpectations: typeof expectations = []; | |
| for (const exp of expectations) { | |
| // If it's a comment/empty, or not Flaky (needs both Failure and Pass) | |
| if (exp.isCommentOrEmpty || !exp.results?.includes('Failure') || !exp.results?.includes('Pass')) { | |
| newExpectations.push(exp); | |
| continue; | |
| } | |
| // It is a flaky test | |
| const testName = exp.testName; | |
| const isFlakyInLuci = clusters.some(c => (c.title || '').includes(testName)); | |
| if (!isFlakyInLuci) { | |
| console.log(`Removing stable test from TestExpectations: ${testName}`); | |
| modified = true; | |
| // Skip adding this to newExpectations, which effectively deletes it | |
| } else { | |
| newExpectations.push(exp); | |
| } | |
| } | |
| if (modified) { | |
| const newContent = serializeExpectations(newExpectations); | |
| fs.writeFileSync(expectationsPath, newContent + '\n', 'utf-8'); | |
| console.log('\nSuccessfully updated test/TestExpectations'); | |
| } else { | |
| console.log('\nNo stable tests found. No changes made.'); | |
| } | |
| } | |
| if (import.meta.main) { | |
| main().catch(err => { | |
| console.error(err); | |
| process.exit(1); | |
| }); | |
| } |