mirror of
https://github.com/web-infra-dev/midscene.git
synced 2025-12-28 07:30:02 +00:00
feat: allow continue-on-error in yaml (#254)
* feat: allow continue on error in yaml #252 * doc: update doc for new param * fix: ignore yaml file in node-modules
This commit is contained in:
parent
de92f3fc13
commit
c91da56431
@ -151,6 +151,7 @@ The `tasks` part is an array indicates the tasks to do. Remember to write a `-`
|
||||
```yaml
|
||||
tasks:
|
||||
- name: <name>
|
||||
continueOnError: <boolean> # optional, default is false
|
||||
flow:
|
||||
# perform an action, this is the shortcut for aiAction
|
||||
- ai: <prompt>
|
||||
|
||||
@ -151,6 +151,7 @@ target:
|
||||
```yaml
|
||||
tasks:
|
||||
- name: <name>
|
||||
continueOnError: <boolean> # 可选,错误时是否继续执行下一个任务,默认 false
|
||||
flow:
|
||||
# 执行一个交互,`ai` 是 `aiAction` 的简写方式
|
||||
- ai: <prompt>
|
||||
|
||||
1
packages/midscene/src/yaml.d.ts
vendored
1
packages/midscene/src/yaml.d.ts
vendored
@ -6,6 +6,7 @@ export interface MidsceneYamlScript {
|
||||
export interface MidsceneYamlTask {
|
||||
name: string;
|
||||
flow: MidsceneYamlFlowItem[];
|
||||
continueOnError?: boolean;
|
||||
}
|
||||
|
||||
export interface MidsceneYamlScriptEnv {
|
||||
|
||||
@ -197,26 +197,31 @@ export class ScriptPlayer {
|
||||
this.setPlayerStatus('running');
|
||||
let errorFlag = false;
|
||||
while (taskIndex < tasks.length) {
|
||||
const taskStatus = this.taskStatusList[taskIndex];
|
||||
this.setTaskStatus(taskIndex, 'running' as any);
|
||||
this.setTaskIndex(taskIndex);
|
||||
|
||||
try {
|
||||
this.setTaskIndex(taskIndex);
|
||||
await this.playTask(this.taskStatusList[taskIndex], this.pageAgent);
|
||||
await this.playTask(taskStatus, this.pageAgent);
|
||||
this.setTaskStatus(taskIndex, 'done' as any);
|
||||
} catch (e) {
|
||||
this.setTaskStatus(taskIndex, 'error' as any, e as Error);
|
||||
this.setPlayerStatus('error');
|
||||
errorFlag = true;
|
||||
|
||||
this.reportFile = agent.reportFile;
|
||||
taskIndex++;
|
||||
continue;
|
||||
if (taskStatus.continueOnError) {
|
||||
// nothing more to do
|
||||
} else {
|
||||
this.reportFile = agent.reportFile;
|
||||
errorFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.reportFile = agent.reportFile;
|
||||
this.setTaskStatus(taskIndex, 'done' as any);
|
||||
taskIndex++;
|
||||
}
|
||||
|
||||
if (!errorFlag) {
|
||||
if (errorFlag) {
|
||||
this.setPlayerStatus('error');
|
||||
} else {
|
||||
this.setPlayerStatus('done');
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import { describe, expect, test, vi } from 'vitest';
|
||||
|
||||
const serverRoot = join(__dirname, 'server_root');
|
||||
|
||||
const runYaml = async (yamlString: string) => {
|
||||
const runYaml = async (yamlString: string, ignoreStatusAssertion = false) => {
|
||||
const script = parseYamlScript(yamlString);
|
||||
const statusUpdate = vi.fn();
|
||||
const player = new ScriptPlayer(
|
||||
@ -18,11 +18,17 @@ const runYaml = async (yamlString: string) => {
|
||||
statusUpdate,
|
||||
);
|
||||
await player.run();
|
||||
expect(statusUpdate).toHaveBeenCalled();
|
||||
assert(
|
||||
player.status === 'done',
|
||||
player.errorInSetup?.message || 'unknown error',
|
||||
);
|
||||
if (!ignoreStatusAssertion) {
|
||||
assert(
|
||||
player.status === 'done',
|
||||
player.errorInSetup?.message || 'unknown error',
|
||||
);
|
||||
expect(statusUpdate).toHaveBeenCalled();
|
||||
}
|
||||
return {
|
||||
player,
|
||||
statusUpdate,
|
||||
};
|
||||
};
|
||||
|
||||
const shouldRunAITest =
|
||||
@ -140,6 +146,44 @@ describe.skipIf(!shouldRunAITest)(
|
||||
await runYaml(yamlString);
|
||||
}).rejects.toThrow(/TimeoutError/i);
|
||||
});
|
||||
|
||||
test('stop on task error', async () => {
|
||||
const yamlString = `
|
||||
target:
|
||||
url: https://www.baidu.com
|
||||
tasks:
|
||||
- name: assert1
|
||||
flow:
|
||||
- aiAssert: this is a food delivery service app
|
||||
- name: assert2
|
||||
flow:
|
||||
- aiAssert: this is a search engine
|
||||
`;
|
||||
|
||||
const { player } = await runYaml(yamlString, true);
|
||||
expect(player.status).toBe('error');
|
||||
expect(player.taskStatusList[0].status).toBe('error');
|
||||
expect(player.taskStatusList[1].status).toBe('init');
|
||||
});
|
||||
|
||||
test('allow continue on task error', async () => {
|
||||
const yamlString = `
|
||||
target:
|
||||
url: https://www.baidu.com
|
||||
tasks:
|
||||
- name: assert1
|
||||
continueOnError: true
|
||||
flow:
|
||||
- aiAssert: this is a food delivery service app
|
||||
- name: assert2
|
||||
flow:
|
||||
- aiAssert: this is a search engine
|
||||
`;
|
||||
const { player } = await runYaml(yamlString, true);
|
||||
expect(player.status).toBe('done');
|
||||
expect(player.taskStatusList[0].status).toBe('error');
|
||||
expect(player.taskStatusList[1].status).toBe('done');
|
||||
});
|
||||
},
|
||||
60 * 1000,
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user