@testspectra/skills 1.1.8-rc.9 → 1.1.11-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/commands/add.js +2 -1
- package/dist/commands/init.js +4 -1
- package/dist/commands/list.js +3 -2
- package/dist/commands/remove.js +4 -1
- package/dist/commands/update.js +29 -7
- package/dist/detector.d.ts +15 -0
- package/dist/detector.js +51 -9
- package/dist/registry.js +1 -4
- package/dist/skills/matchers-and-assertions/SKILL.md +9 -9
- package/package.json +1 -1
- package/skills/matchers-and-assertions/SKILL.md +9 -9
package/README.md
CHANGED
|
@@ -50,16 +50,16 @@ overrides the saved selection for a single invocation.
|
|
|
50
50
|
|
|
51
51
|
## Available Skills
|
|
52
52
|
|
|
53
|
-
| Skill
|
|
54
|
-
|
|
|
55
|
-
| `workspace-structure`
|
|
56
|
-
| `spec-and-suite-authoring`
|
|
57
|
-
| `page-objects-and-selectors` | Page Object pattern (`Spectra.get`/`getAll`), the `~`/`#` selector contract
|
|
58
|
-
| `matchers-and-assertions`
|
|
59
|
-
| `shared-steps-and-actions`
|
|
60
|
-
| `lifecycle-hooks`
|
|
61
|
-
| `fixtures-data`
|
|
62
|
-
| `network-interception`
|
|
53
|
+
| Skill | Covers |
|
|
54
|
+
| :--------------------------- | :------------------------------------------------------------------------------------------------ |
|
|
55
|
+
| `workspace-structure` | Directory layout, zero-import architecture, file suffixes, `spectra.config.ts`, core CLI commands |
|
|
56
|
+
| `spec-and-suite-authoring` | `suite.md` / `spec.md` frontmatter, the paired `*.test.ts` script, every `spectra lint` rule |
|
|
57
|
+
| `page-objects-and-selectors` | Page Object pattern (`Spectra.get`/`getAll`), the `~`/`#` selector contract |
|
|
58
|
+
| `matchers-and-assertions` | Full element action/assertion/collection matcher and global `Spectra.*` command reference |
|
|
59
|
+
| `shared-steps-and-actions` | `Step.*` business workflows vs `support/actions/*` technical utilities |
|
|
60
|
+
| `lifecycle-hooks` | `global-hooks/` vs `specs/<suite>/hooks/`, execution order, failure cascade |
|
|
61
|
+
| `fixtures-data` | `fixtures/*.json` and the ambient `Fixture.*` namespace |
|
|
62
|
+
| `network-interception` | `Spectra.intercept()` mocking, polling, and failure-simulation patterns |
|
|
63
63
|
|
|
64
64
|
Each skill is grounded in `docs/v2/` and the reference workspace at `cli/templates/default`, so an
|
|
65
65
|
AI coding agent scaffolding TestSpectra scripts produces code that already passes `spectra lint`.
|
package/dist/commands/add.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// oxlint-disable no-console
|
|
2
2
|
import { intro, outro, multiselect, isCancel, cancel } from '@clack/prompts';
|
|
3
|
-
import { installSkill } from '../detector.js';
|
|
3
|
+
import { installSkill, addConfiguredSkills } from '../detector.js';
|
|
4
4
|
import { loadAllSkills, getSkill } from '../registry.js';
|
|
5
5
|
export async function addSkills(skillIds, baseDir = process.cwd(), agentIds) {
|
|
6
6
|
intro('\x1b[1m\x1b[36m➕ Install TestSpectra Script-Authoring Skills\x1b[0m');
|
|
@@ -36,6 +36,7 @@ export async function addSkills(skillIds, baseDir = process.cwd(), agentIds) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
if (installedList.length > 0) {
|
|
39
|
+
addConfiguredSkills(baseDir, installedList);
|
|
39
40
|
outro(`\x1b[32mSuccessfully installed ${installedList.length} skill(s)!\x1b[0m`);
|
|
40
41
|
}
|
|
41
42
|
else {
|
package/dist/commands/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// oxlint-disable no-console
|
|
2
2
|
import { intro, outro, multiselect, isCancel, cancel } from '@clack/prompts';
|
|
3
|
-
import { KNOWN_AGENTS, writeAgentConfig, installSkill } from '../detector.js';
|
|
3
|
+
import { KNOWN_AGENTS, writeAgentConfig, installSkill, addConfiguredSkills } from '../detector.js';
|
|
4
4
|
import { loadAllSkills, getSkill } from '../registry.js';
|
|
5
5
|
export async function initSkills(baseDir = process.cwd()) {
|
|
6
6
|
intro('\x1b[1m\x1b[36m🧭 TestSpectra Skills Setup\x1b[0m');
|
|
@@ -50,5 +50,8 @@ export async function initSkills(baseDir = process.cwd()) {
|
|
|
50
50
|
console.log(` \x1b[32m✔\x1b[0m Installed \x1b[1m${skill.id}\x1b[0m -> \x1b[2m${p}\x1b[0m`);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
if (installedList.length > 0) {
|
|
54
|
+
addConfiguredSkills(baseDir, installedList);
|
|
55
|
+
}
|
|
53
56
|
outro(`\x1b[32mSetup complete!\x1b[0m Installed ${installedList.length} skill(s) for agent(s): ${agentIds.join(', ')}.`);
|
|
54
57
|
}
|
package/dist/commands/list.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// oxlint-disable no-console
|
|
2
2
|
import { intro, outro } from '@clack/prompts';
|
|
3
|
-
import { getAgentSkillDirs, isSkillInstalled } from '../detector.js';
|
|
3
|
+
import { getAgentSkillDirs, isSkillInstalled, readConfiguredSkills } from '../detector.js';
|
|
4
4
|
import { loadAllSkills } from '../registry.js';
|
|
5
5
|
export function listSkills(baseDir = process.cwd(), agentIds) {
|
|
6
6
|
intro('\x1b[1m\x1b[36m📦 TestSpectra Skills Registry\x1b[0m');
|
|
7
7
|
const allSkills = loadAllSkills();
|
|
8
8
|
const targetDirs = getAgentSkillDirs(baseDir, agentIds);
|
|
9
|
+
const configured = new Set(readConfiguredSkills(baseDir) ?? []);
|
|
9
10
|
if (allSkills.length === 0) {
|
|
10
11
|
console.log('No skills found in registry.');
|
|
11
12
|
outro('Done.');
|
|
@@ -13,7 +14,7 @@ export function listSkills(baseDir = process.cwd(), agentIds) {
|
|
|
13
14
|
}
|
|
14
15
|
console.log(`\nAgent directories: \x1b[2m${targetDirs.join(', ')}\x1b[0m\n`);
|
|
15
16
|
for (const skill of allSkills) {
|
|
16
|
-
const installed = isSkillInstalled(skill.id, baseDir, agentIds);
|
|
17
|
+
const installed = configured.has(skill.id) || isSkillInstalled(skill.id, baseDir, agentIds);
|
|
17
18
|
const statusBadge = installed ? '\x1b[32m[Installed]\x1b[0m' : '\x1b[90m[Available]\x1b[0m';
|
|
18
19
|
console.log(` ${statusBadge} \x1b[1m${skill.id}\x1b[0m`);
|
|
19
20
|
console.log(` \x1b[90m${skill.description}\x1b[0m\n`);
|
package/dist/commands/remove.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// oxlint-disable no-console
|
|
2
2
|
import { intro, outro } from '@clack/prompts';
|
|
3
|
-
import { removeSkill } from '../detector.js';
|
|
3
|
+
import { removeSkill, removeConfiguredSkills } from '../detector.js';
|
|
4
4
|
export function removeSkills(skillIds, baseDir = process.cwd(), agentIds) {
|
|
5
5
|
intro('\x1b[1m\x1b[31m🗑️ Remove TestSpectra Skills\x1b[0m');
|
|
6
6
|
const targets = skillIds.filter(Boolean);
|
|
@@ -22,5 +22,8 @@ export function removeSkills(skillIds, baseDir = process.cwd(), agentIds) {
|
|
|
22
22
|
console.log(` \x1b[90m- Skill "${id}" was not installed.\x1b[0m`);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
if (removedList.length > 0) {
|
|
26
|
+
removeConfiguredSkills(baseDir, removedList);
|
|
27
|
+
}
|
|
25
28
|
outro(`\x1b[32mCompleted. Removed ${removedList.length} skill(s).\x1b[0m`);
|
|
26
29
|
}
|
package/dist/commands/update.js
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
// oxlint-disable no-console
|
|
2
2
|
import { intro, outro } from '@clack/prompts';
|
|
3
|
-
import { getInstalledSkills, installSkill } from '../detector.js';
|
|
4
|
-
import { getSkill } from '../registry.js';
|
|
3
|
+
import { addConfiguredSkills, getInstalledSkills, installSkill, readConfiguredSkills } from '../detector.js';
|
|
4
|
+
import { getSkill, loadAllSkills } from '../registry.js';
|
|
5
5
|
export function updateSkills(skillIds = [], baseDir = process.cwd(), agentIds) {
|
|
6
6
|
intro('\x1b[1m\x1b[36m🔄 Update TestSpectra Skills\x1b[0m');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const allSkills = loadAllSkills();
|
|
8
|
+
const knownSkillIds = new Set(allSkills.map((s) => s.id));
|
|
9
|
+
const explicitTargets = skillIds.filter(Boolean);
|
|
10
|
+
const isExplicit = explicitTargets.length > 0;
|
|
11
|
+
// Determine which skills to update:
|
|
12
|
+
// 1. Explicit skill IDs if provided
|
|
13
|
+
// 2. Configured skill IDs from .spectra-skills.json (filtered against registry)
|
|
14
|
+
// 3. Fallback to installed directory detection (filtered against registry)
|
|
15
|
+
let targets;
|
|
16
|
+
if (isExplicit) {
|
|
17
|
+
targets = explicitTargets;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const configuredSkills = readConfiguredSkills(baseDir);
|
|
21
|
+
if (configuredSkills && configuredSkills.length > 0) {
|
|
22
|
+
targets = configuredSkills.filter((id) => knownSkillIds.has(id));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
targets = getInstalledSkills(baseDir, agentIds).filter((id) => knownSkillIds.has(id));
|
|
26
|
+
}
|
|
10
27
|
}
|
|
11
28
|
if (targets.length === 0) {
|
|
12
|
-
console.log('No installed skills found in project to update.');
|
|
29
|
+
console.log('No installed TestSpectra skills found in project to update.');
|
|
13
30
|
outro('Done.');
|
|
14
31
|
return;
|
|
15
32
|
}
|
|
@@ -17,7 +34,9 @@ export function updateSkills(skillIds = [], baseDir = process.cwd(), agentIds) {
|
|
|
17
34
|
for (const id of targets) {
|
|
18
35
|
const skill = getSkill(id);
|
|
19
36
|
if (!skill) {
|
|
20
|
-
|
|
37
|
+
if (isExplicit) {
|
|
38
|
+
console.log(`\x1b[33m⚠️ Skill "${id}" not found in current registry.\x1b[0m`);
|
|
39
|
+
}
|
|
21
40
|
continue;
|
|
22
41
|
}
|
|
23
42
|
const paths = installSkill(skill, baseDir, agentIds);
|
|
@@ -26,5 +45,8 @@ export function updateSkills(skillIds = [], baseDir = process.cwd(), agentIds) {
|
|
|
26
45
|
console.log(` \x1b[32m✔\x1b[0m Updated \x1b[1m${skill.id}\x1b[0m -> \x1b[2m${p}\x1b[0m`);
|
|
27
46
|
}
|
|
28
47
|
}
|
|
48
|
+
if (updatedList.length > 0) {
|
|
49
|
+
addConfiguredSkills(baseDir, updatedList);
|
|
50
|
+
}
|
|
29
51
|
outro(`\x1b[32mSuccessfully updated ${updatedList.length} skill(s)!\x1b[0m`);
|
|
30
52
|
}
|
package/dist/detector.d.ts
CHANGED
|
@@ -10,10 +10,25 @@ export interface AgentDefinition {
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const KNOWN_AGENTS: AgentDefinition[];
|
|
12
12
|
export declare function getKnownAgentIds(): string[];
|
|
13
|
+
export declare const CONFIG_FILENAME = ".spectra-skills.json";
|
|
14
|
+
export interface SkillsConfig {
|
|
15
|
+
agents?: string[];
|
|
16
|
+
skills?: string[];
|
|
17
|
+
}
|
|
18
|
+
/** Reads the skills and agent selection persisted in `.spectra-skills.json`, if any. */
|
|
19
|
+
export declare function readSkillsConfig(baseDir?: string): SkillsConfig;
|
|
20
|
+
/** Persists partial skills configuration in `.spectra-skills.json`. */
|
|
21
|
+
export declare function writeSkillsConfig(baseDir: string, patch: Partial<SkillsConfig>): string;
|
|
13
22
|
/** Reads the agent selection persisted by `spectra-skills init`, if any. */
|
|
14
23
|
export declare function readAgentConfig(baseDir?: string): string[] | undefined;
|
|
15
24
|
/** Persists the agent selection chosen via `spectra-skills init` for future add/update/remove/list calls. */
|
|
16
25
|
export declare function writeAgentConfig(baseDir: string, agentIds: string[]): string;
|
|
26
|
+
/** Reads the installed skill IDs recorded in `.spectra-skills.json`, if any. */
|
|
27
|
+
export declare function readConfiguredSkills(baseDir?: string): string[] | undefined;
|
|
28
|
+
/** Adds skill IDs to `.spectra-skills.json`. */
|
|
29
|
+
export declare function addConfiguredSkills(baseDir: string, skillIds: string[]): void;
|
|
30
|
+
/** Removes skill IDs from `.spectra-skills.json`. */
|
|
31
|
+
export declare function removeConfiguredSkills(baseDir: string, skillIds: string[]): void;
|
|
17
32
|
/** Splits a comma/whitespace separated --agent value and reports any id not in KNOWN_AGENTS. */
|
|
18
33
|
export declare function resolveAgentSelection(raw?: string): {
|
|
19
34
|
ids: string[];
|
package/dist/detector.js
CHANGED
|
@@ -19,28 +19,70 @@ export const KNOWN_AGENTS = [
|
|
|
19
19
|
export function getKnownAgentIds() {
|
|
20
20
|
return KNOWN_AGENTS.map((a) => a.id);
|
|
21
21
|
}
|
|
22
|
-
const CONFIG_FILENAME = '.spectra-skills.json';
|
|
23
|
-
/** Reads the agent selection persisted
|
|
24
|
-
export function
|
|
22
|
+
export const CONFIG_FILENAME = '.spectra-skills.json';
|
|
23
|
+
/** Reads the skills and agent selection persisted in `.spectra-skills.json`, if any. */
|
|
24
|
+
export function readSkillsConfig(baseDir = process.cwd()) {
|
|
25
25
|
const configPath = path.join(baseDir, CONFIG_FILENAME);
|
|
26
26
|
if (!fs.existsSync(configPath))
|
|
27
|
-
return
|
|
27
|
+
return {};
|
|
28
28
|
try {
|
|
29
29
|
const parsed = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
30
30
|
const known = new Set(getKnownAgentIds());
|
|
31
31
|
const agents = (parsed.agents ?? []).filter((id) => known.has(id));
|
|
32
|
-
|
|
32
|
+
const skills = Array.isArray(parsed.skills) ? parsed.skills.filter(Boolean) : undefined;
|
|
33
|
+
return {
|
|
34
|
+
agents: agents.length > 0 ? agents : undefined,
|
|
35
|
+
skills,
|
|
36
|
+
};
|
|
33
37
|
}
|
|
34
38
|
catch {
|
|
35
|
-
return
|
|
39
|
+
return {};
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
|
-
/** Persists
|
|
39
|
-
export function
|
|
42
|
+
/** Persists partial skills configuration in `.spectra-skills.json`. */
|
|
43
|
+
export function writeSkillsConfig(baseDir, patch) {
|
|
40
44
|
const configPath = path.join(baseDir, CONFIG_FILENAME);
|
|
41
|
-
|
|
45
|
+
const existing = readSkillsConfig(baseDir);
|
|
46
|
+
const updated = {
|
|
47
|
+
agents: patch.agents !== undefined ? patch.agents : existing.agents,
|
|
48
|
+
skills: patch.skills !== undefined ? patch.skills : existing.skills,
|
|
49
|
+
};
|
|
50
|
+
const out = {};
|
|
51
|
+
if (updated.agents && updated.agents.length > 0)
|
|
52
|
+
out.agents = updated.agents;
|
|
53
|
+
if (updated.skills && updated.skills.length > 0)
|
|
54
|
+
out.skills = updated.skills;
|
|
55
|
+
fs.writeFileSync(configPath, JSON.stringify(out, null, 2) + '\n', 'utf-8');
|
|
42
56
|
return configPath;
|
|
43
57
|
}
|
|
58
|
+
/** Reads the agent selection persisted by `spectra-skills init`, if any. */
|
|
59
|
+
export function readAgentConfig(baseDir = process.cwd()) {
|
|
60
|
+
return readSkillsConfig(baseDir).agents;
|
|
61
|
+
}
|
|
62
|
+
/** Persists the agent selection chosen via `spectra-skills init` for future add/update/remove/list calls. */
|
|
63
|
+
export function writeAgentConfig(baseDir, agentIds) {
|
|
64
|
+
return writeSkillsConfig(baseDir, { agents: agentIds });
|
|
65
|
+
}
|
|
66
|
+
/** Reads the installed skill IDs recorded in `.spectra-skills.json`, if any. */
|
|
67
|
+
export function readConfiguredSkills(baseDir = process.cwd()) {
|
|
68
|
+
return readSkillsConfig(baseDir).skills;
|
|
69
|
+
}
|
|
70
|
+
/** Adds skill IDs to `.spectra-skills.json`. */
|
|
71
|
+
export function addConfiguredSkills(baseDir, skillIds) {
|
|
72
|
+
const existing = new Set(readConfiguredSkills(baseDir) ?? []);
|
|
73
|
+
for (const id of skillIds) {
|
|
74
|
+
existing.add(id);
|
|
75
|
+
}
|
|
76
|
+
writeSkillsConfig(baseDir, { skills: Array.from(existing).sort() });
|
|
77
|
+
}
|
|
78
|
+
/** Removes skill IDs from `.spectra-skills.json`. */
|
|
79
|
+
export function removeConfiguredSkills(baseDir, skillIds) {
|
|
80
|
+
const existing = new Set(readConfiguredSkills(baseDir) ?? []);
|
|
81
|
+
for (const id of skillIds) {
|
|
82
|
+
existing.delete(id);
|
|
83
|
+
}
|
|
84
|
+
writeSkillsConfig(baseDir, { skills: Array.from(existing).sort() });
|
|
85
|
+
}
|
|
44
86
|
/** Splits a comma/whitespace separated --agent value and reports any id not in KNOWN_AGENTS. */
|
|
45
87
|
export function resolveAgentSelection(raw) {
|
|
46
88
|
if (!raw)
|
package/dist/registry.js
CHANGED
|
@@ -19,10 +19,7 @@ function parseSkillContent(id, content) {
|
|
|
19
19
|
}
|
|
20
20
|
function findSkillsDir() {
|
|
21
21
|
// dist/registry.js -> ../skills ; src/registry.ts (ts-node/dev) -> ../skills
|
|
22
|
-
const candidates = [
|
|
23
|
-
path.resolve(__dirname, '../skills'),
|
|
24
|
-
path.resolve(__dirname, '../../skills'),
|
|
25
|
-
];
|
|
22
|
+
const candidates = [path.resolve(__dirname, '../skills'), path.resolve(__dirname, '../../skills')];
|
|
26
23
|
return candidates.find((dir) => fs.existsSync(dir));
|
|
27
24
|
}
|
|
28
25
|
export function loadAllSkills() {
|
|
@@ -103,16 +103,16 @@ collection carry the scope forward too. No behavior difference on web vs. Androi
|
|
|
103
103
|
|
|
104
104
|
## 5. Global `Spectra.*` Commands
|
|
105
105
|
|
|
106
|
-
| Category | Syntax
|
|
107
|
-
| :------------- |
|
|
108
|
-
| Navigation | `await Spectra.navigate("/login")` / `.back()` / `.forward()` / `.refresh()`
|
|
106
|
+
| Category | Syntax |
|
|
107
|
+
| :------------- | :------------------------------------------------------------------------------------------------------------------------------- |
|
|
108
|
+
| Navigation | `await Spectra.navigate("/login")` / `.back()` / `.forward()` / `.refresh()` |
|
|
109
109
|
| Element query | `Spectra.get(selector)` / `Spectra.getAll(selector)` — chain `.get()`/`.getAll()` on the result to scope a lookup, see section 4 |
|
|
110
|
-
| Window | `await Spectra.setViewport(1920, 1080)`
|
|
111
|
-
| Timing | `await Spectra.wait(1000)`
|
|
112
|
-
| Keyboard | `await Spectra.pressKey("Enter")`
|
|
113
|
-
| Scroll | `await Spectra.scroll({ direction: "down", pixels: 400 })`
|
|
114
|
-
| Mobile gesture | `await Spectra.swipe({ direction: "left", distance: 300 })`
|
|
115
|
-
| Network mock | `const mock = await Spectra.intercept({ url, method, response })` — see the `network-interception` skill
|
|
110
|
+
| Window | `await Spectra.setViewport(1920, 1080)` |
|
|
111
|
+
| Timing | `await Spectra.wait(1000)` |
|
|
112
|
+
| Keyboard | `await Spectra.pressKey("Enter")` |
|
|
113
|
+
| Scroll | `await Spectra.scroll({ direction: "down", pixels: 400 })` |
|
|
114
|
+
| Mobile gesture | `await Spectra.swipe({ direction: "left", distance: 300 })` |
|
|
115
|
+
| Network mock | `const mock = await Spectra.intercept({ url, method, response })` — see the `network-interception` skill |
|
|
116
116
|
|
|
117
117
|
## 6. `Spectra.browser.*` — Browser/Context Level
|
|
118
118
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@testspectra/skills",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.11-rc.3",
|
|
4
4
|
"description": "Installer & manager for modular AI agent skills that standardize TestSpectra script authoring (specs, page objects, steps, actions, hooks, fixtures, matchers)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -103,16 +103,16 @@ collection carry the scope forward too. No behavior difference on web vs. Androi
|
|
|
103
103
|
|
|
104
104
|
## 5. Global `Spectra.*` Commands
|
|
105
105
|
|
|
106
|
-
| Category | Syntax
|
|
107
|
-
| :------------- |
|
|
108
|
-
| Navigation | `await Spectra.navigate("/login")` / `.back()` / `.forward()` / `.refresh()`
|
|
106
|
+
| Category | Syntax |
|
|
107
|
+
| :------------- | :------------------------------------------------------------------------------------------------------------------------------- |
|
|
108
|
+
| Navigation | `await Spectra.navigate("/login")` / `.back()` / `.forward()` / `.refresh()` |
|
|
109
109
|
| Element query | `Spectra.get(selector)` / `Spectra.getAll(selector)` — chain `.get()`/`.getAll()` on the result to scope a lookup, see section 4 |
|
|
110
|
-
| Window | `await Spectra.setViewport(1920, 1080)`
|
|
111
|
-
| Timing | `await Spectra.wait(1000)`
|
|
112
|
-
| Keyboard | `await Spectra.pressKey("Enter")`
|
|
113
|
-
| Scroll | `await Spectra.scroll({ direction: "down", pixels: 400 })`
|
|
114
|
-
| Mobile gesture | `await Spectra.swipe({ direction: "left", distance: 300 })`
|
|
115
|
-
| Network mock | `const mock = await Spectra.intercept({ url, method, response })` — see the `network-interception` skill
|
|
110
|
+
| Window | `await Spectra.setViewport(1920, 1080)` |
|
|
111
|
+
| Timing | `await Spectra.wait(1000)` |
|
|
112
|
+
| Keyboard | `await Spectra.pressKey("Enter")` |
|
|
113
|
+
| Scroll | `await Spectra.scroll({ direction: "down", pixels: 400 })` |
|
|
114
|
+
| Mobile gesture | `await Spectra.swipe({ direction: "left", distance: 300 })` |
|
|
115
|
+
| Network mock | `const mock = await Spectra.intercept({ url, method, response })` — see the `network-interception` skill |
|
|
116
116
|
|
|
117
117
|
## 6. `Spectra.browser.*` — Browser/Context Level
|
|
118
118
|
|