Skip to content

Commit 8491f3c

Browse files
download specific artifacts
1 parent ae09441 commit 8491f3c

4 files changed

Lines changed: 63 additions & 15 deletions

File tree

src/cli.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import MaestroOptions, {
1818
Orientation,
1919
ThrottleNetwork,
2020
ReportFormat,
21+
ArtifactDownloadMode,
2122
} from './models/maestro_options';
2223
import Maestro from './providers/maestro';
2324
import Login from './providers/login';
@@ -297,8 +298,9 @@ const maestroCommand = program
297298
)
298299
// Artifact download
299300
.option(
300-
'--download-artifacts',
301-
'Download test artifacts (logs, screenshots, video) after completion.',
301+
'--download-artifacts [mode]',
302+
'Download test artifacts after completion. Mode: all (default) or failed.',
303+
(val) => (val === 'failed' ? 'failed' : 'all') as ArtifactDownloadMode,
302304
)
303305
.option(
304306
'--artifacts-output-dir <path>',
@@ -367,7 +369,10 @@ const maestroCommand = program
367369
report: args.report,
368370
reportOutputDir: args.reportOutputDir,
369371
realDevice: args.realDevice,
370-
downloadArtifacts: args.downloadArtifacts,
372+
downloadArtifacts:
373+
args.downloadArtifacts === true
374+
? 'all'
375+
: (args.downloadArtifacts as ArtifactDownloadMode | undefined),
371376
artifactsOutputDir: args.artifactsOutputDir,
372377
ignoreChecksumCheck: args.ignoreChecksumCheck,
373378
shardSplit: args.shardSplit,

src/models/maestro_options.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface MaestroConfig {
88
export type Orientation = 'PORTRAIT' | 'LANDSCAPE';
99
export type ThrottleNetwork = '4G' | '3G' | 'Edge' | 'airplane' | 'disable';
1010
export type ReportFormat = 'html' | 'junit';
11+
export type ArtifactDownloadMode = 'all' | 'failed';
1112

1213
export interface MaestroCapabilities {
1314
platformName?: 'Android' | 'iOS';
@@ -50,7 +51,7 @@ export default class MaestroOptions {
5051
private _report?: ReportFormat;
5152
private _reportOutputDir?: string;
5253
private _realDevice: boolean;
53-
private _downloadArtifacts: boolean;
54+
private _downloadArtifacts?: ArtifactDownloadMode;
5455
private _artifactsOutputDir?: string;
5556
private _ignoreChecksumCheck: boolean;
5657
private _shardSplit?: number;
@@ -77,7 +78,7 @@ export default class MaestroOptions {
7778
report?: ReportFormat;
7879
reportOutputDir?: string;
7980
realDevice?: boolean;
80-
downloadArtifacts?: boolean;
81+
downloadArtifacts?: ArtifactDownloadMode;
8182
artifactsOutputDir?: string;
8283
ignoreChecksumCheck?: boolean;
8384
shardSplit?: number;
@@ -103,7 +104,7 @@ export default class MaestroOptions {
103104
this._report = options?.report;
104105
this._reportOutputDir = options?.reportOutputDir;
105106
this._realDevice = options?.realDevice ?? false;
106-
this._downloadArtifacts = options?.downloadArtifacts ?? false;
107+
this._downloadArtifacts = options?.downloadArtifacts;
107108
this._artifactsOutputDir = options?.artifactsOutputDir;
108109
this._ignoreChecksumCheck = options?.ignoreChecksumCheck ?? false;
109110
this._shardSplit = options?.shardSplit;
@@ -189,7 +190,7 @@ export default class MaestroOptions {
189190
return this._realDevice;
190191
}
191192

192-
public get downloadArtifacts(): boolean {
193+
public get downloadArtifacts(): ArtifactDownloadMode | undefined {
193194
return this._downloadArtifacts;
194195
}
195196

src/providers/maestro.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,8 +1522,30 @@ export default class Maestro {
15221522
private async downloadArtifacts(runs: MaestroRunInfo[]): Promise<void> {
15231523
if (!this.options.downloadArtifacts) return;
15241524

1525+
// Filter runs based on download mode
1526+
const downloadMode = this.options.downloadArtifacts;
1527+
const runsToDownload =
1528+
downloadMode === 'failed'
1529+
? runs.filter((run) => run.success !== 1)
1530+
: runs;
1531+
1532+
if (runsToDownload.length === 0) {
1533+
if (!this.options.quiet) {
1534+
if (downloadMode === 'failed') {
1535+
logger.info('No failed runs to download artifacts for.');
1536+
} else {
1537+
logger.info('No runs to download artifacts for.');
1538+
}
1539+
}
1540+
return;
1541+
}
1542+
15251543
if (!this.options.quiet) {
1526-
logger.info('Downloading artifacts...');
1544+
if (downloadMode === 'failed') {
1545+
logger.info(`Downloading artifacts for ${runsToDownload.length} failed run(s)...`);
1546+
} else {
1547+
logger.info('Downloading artifacts...');
1548+
}
15271549
}
15281550

15291551
const outputDir = this.options.artifactsOutputDir || process.cwd();
@@ -1533,7 +1555,7 @@ export default class Maestro {
15331555
);
15341556

15351557
try {
1536-
for (const run of runs) {
1558+
for (const run of runsToDownload) {
15371559
try {
15381560
if (!this.options.quiet) {
15391561
logger.info(` Waiting for artifacts sync for run ${run.id}...`);

tests/providers/maestro.test.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ describe('Maestro', () => {
15751575
'path/to/app.apk',
15761576
'path/to/flows',
15771577
'Pixel 6',
1578-
{ downloadArtifacts: true },
1578+
{ downloadArtifacts: 'all' },
15791579
);
15801580
const maestroWithArtifacts = new Maestro(
15811581
mockCredentials,
@@ -1596,7 +1596,7 @@ describe('Maestro', () => {
15961596
'path/to/flows',
15971597
'Pixel 6',
15981598
{
1599-
downloadArtifacts: true,
1599+
downloadArtifacts: 'all',
16001600
artifactsOutputDir: './artifacts',
16011601
},
16021602
);
@@ -1616,13 +1616,33 @@ describe('Maestro', () => {
16161616
await expect(maestroWithArtifacts['validate']()).resolves.toBe(true);
16171617
});
16181618

1619+
it('should pass validation when downloadArtifacts is set to failed mode', async () => {
1620+
const optionsWithArtifacts = new MaestroOptions(
1621+
'path/to/app.apk',
1622+
'path/to/flows',
1623+
'Pixel 6',
1624+
{ downloadArtifacts: 'failed' },
1625+
);
1626+
const maestroWithArtifacts = new Maestro(
1627+
mockCredentials,
1628+
optionsWithArtifacts,
1629+
);
1630+
1631+
fs.promises.access = jest
1632+
.fn()
1633+
.mockResolvedValueOnce(undefined)
1634+
.mockResolvedValueOnce(undefined);
1635+
1636+
await expect(maestroWithArtifacts['validate']()).resolves.toBe(true);
1637+
});
1638+
16191639
it('should generate zip filename from --name option', async () => {
16201640
const optionsWithName = new MaestroOptions(
16211641
'path/to/app.apk',
16221642
'path/to/flows',
16231643
'Pixel 6',
16241644
{
1625-
downloadArtifacts: true,
1645+
downloadArtifacts: 'all',
16261646
name: 'my-test-run',
16271647
},
16281648
);
@@ -1641,7 +1661,7 @@ describe('Maestro', () => {
16411661
'path/to/flows',
16421662
'Pixel 6',
16431663
{
1644-
downloadArtifacts: true,
1664+
downloadArtifacts: 'all',
16451665
name: 'my test/run:v1.0',
16461666
},
16471667
);
@@ -1659,7 +1679,7 @@ describe('Maestro', () => {
16591679
'path/to/app.apk',
16601680
'path/to/flows',
16611681
'Pixel 6',
1662-
{ downloadArtifacts: true },
1682+
{ downloadArtifacts: 'all' },
16631683
);
16641684
const maestroWithoutName = new Maestro(
16651685
mockCredentials,
@@ -1676,7 +1696,7 @@ describe('Maestro', () => {
16761696
'path/to/flows',
16771697
'Pixel 6',
16781698
{
1679-
downloadArtifacts: true,
1699+
downloadArtifacts: 'all',
16801700
name: 'existing-name',
16811701
},
16821702
);

0 commit comments

Comments
 (0)