testdriverai 7.2.43 → 7.2.45
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/.github/workflows/acceptance-windows-scheduled.yaml +24 -15
- package/.github/workflows/acceptance.yaml +18 -16
- package/.github/workflows/windows-self-hosted.yaml +68 -0
- package/docs/v7/aws-setup.mdx +142 -144
- package/interfaces/cli/commands/init.js +1 -1
- package/lib/core/Dashcam.js +17 -16
- package/lib/vitest/hooks.mjs +13 -0
- package/lib/vitest/setup-aws.mjs +225 -0
- package/lib/vitest/setup-self-hosted.mjs +136 -0
- package/package.json +2 -1
- package/sdk.js +40 -9
- package/test/testdriver/ai.test.mjs +1 -1
- package/test/testdriver/assert.test.mjs +3 -1
- package/test/testdriver/chrome-extension.test.mjs +2 -2
- package/test/testdriver/drag-and-drop.test.mjs +1 -1
- package/test/testdriver/element-not-found.test.mjs +1 -1
- package/test/testdriver/exec-output.test.mjs +1 -1
- package/test/testdriver/exec-pwsh.test.mjs +1 -1
- package/test/testdriver/focus-window.test.mjs +1 -1
- package/test/testdriver/formatted-logging.test.mjs +1 -1
- package/test/testdriver/hover-image.test.mjs +2 -2
- package/test/testdriver/hover-text-with-description.test.mjs +2 -2
- package/test/testdriver/hover-text.test.mjs +1 -1
- package/test/testdriver/installer.test.mjs +2 -2
- package/test/testdriver/launch-vscode-linux.test.mjs +2 -2
- package/test/testdriver/match-image.test.mjs +2 -2
- package/test/testdriver/press-keys.test.mjs +1 -1
- package/test/testdriver/prompt.test.mjs +1 -1
- package/test/testdriver/scroll-keyboard.test.mjs +1 -1
- package/test/testdriver/scroll-until-image.test.mjs +1 -1
- package/test/testdriver/scroll-until-text.test.mjs +2 -2
- package/test/testdriver/scroll.test.mjs +1 -1
- package/test/testdriver/type.test.mjs +2 -2
- package/test/testdriver/windows-installer.test.mjs +1 -1
- package/vitest.config.mjs +4 -1
- package/setup/aws/self-hosted.yml +0 -111
|
@@ -15,7 +15,7 @@ describe("Chrome Extension Test", () => {
|
|
|
15
15
|
|
|
16
16
|
console.log('connecting to', process.env.TD_IP)
|
|
17
17
|
|
|
18
|
-
const testdriver = TestDriver(context, { ip: process.env.TD_IP });
|
|
18
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
19
19
|
|
|
20
20
|
// Wait for connection to be ready before running exec
|
|
21
21
|
await testdriver.ready();
|
|
@@ -68,7 +68,7 @@ describe("Chrome Extension Test", () => {
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it("should load Loom from Chrome Web Store by extensionId", async (context) => {
|
|
71
|
-
const testdriver = TestDriver(context);
|
|
71
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
72
72
|
|
|
73
73
|
// Launch Chrome with Loom loaded by its Chrome Web Store ID
|
|
74
74
|
// Loom ID: liecbddmkiiihnedobmlmillhodjkdmb
|
|
@@ -12,7 +12,7 @@ describe("Drag and Drop Test", () => {
|
|
|
12
12
|
it.skipIf(isLinux)(
|
|
13
13
|
'should drag "New Text Document" to "Recycle Bin"',
|
|
14
14
|
async (context) => {
|
|
15
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
15
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
16
16
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
17
17
|
|
|
18
18
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Element Not Found Test", () => {
|
|
10
10
|
it("should handle non-existent element gracefully without timing out", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
//
|
|
@@ -10,7 +10,7 @@ describe.skip("Exec Output Test", () => {
|
|
|
10
10
|
it(
|
|
11
11
|
"should set date using PowerShell and navigate to calendar",
|
|
12
12
|
async (context) => {
|
|
13
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
14
14
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
15
|
|
|
16
16
|
//
|
|
@@ -10,7 +10,7 @@ describe.skip("Exec PowerShell Test", () => {
|
|
|
10
10
|
it(
|
|
11
11
|
"should generate random email using PowerShell and enter it",
|
|
12
12
|
async (context) => {
|
|
13
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
14
14
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
15
|
|
|
16
16
|
//
|
|
@@ -10,7 +10,7 @@ describe("Focus Window Test", () => {
|
|
|
10
10
|
it.skip(
|
|
11
11
|
"should click Microsoft Edge icon and focus Google Chrome",
|
|
12
12
|
async (context) => {
|
|
13
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
14
14
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
15
|
|
|
16
16
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Formatted Logging Test", () => {
|
|
10
10
|
it("should demonstrate formatted logs in dashcam replay", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
// Find and click - logs will be nicely formatted
|
|
@@ -15,7 +15,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
15
15
|
await client.focusApplication("Google Chrome");
|
|
16
16
|
const password = await client.extract("the password");
|
|
17
17
|
const usernameField = await client.find(
|
|
18
|
-
"
|
|
18
|
+
"username input",
|
|
19
19
|
);
|
|
20
20
|
await usernameField.click();
|
|
21
21
|
await client.type(username);
|
|
@@ -27,7 +27,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
27
27
|
|
|
28
28
|
describe("Hover Image Test", () => {
|
|
29
29
|
it("should click on shopping cart icon and verify empty cart", async (context) => {
|
|
30
|
-
const testdriver = TestDriver(context, { ip: process.env.TD_IP });
|
|
30
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
31
31
|
|
|
32
32
|
// provision.chrome() automatically calls ready() and starts dashcam
|
|
33
33
|
await testdriver.provision.chrome({
|
|
@@ -15,7 +15,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
15
15
|
await client.focusApplication("Google Chrome");
|
|
16
16
|
const password = await client.extract("the password");
|
|
17
17
|
const usernameField = await client.find(
|
|
18
|
-
"
|
|
18
|
+
"username input",
|
|
19
19
|
);
|
|
20
20
|
await usernameField.click();
|
|
21
21
|
await client.type(username);
|
|
@@ -27,7 +27,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
27
27
|
|
|
28
28
|
describe("Hover Text With Description Test", () => {
|
|
29
29
|
it("should add TestDriver Hat to cart and verify", async (context) => {
|
|
30
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
30
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
31
31
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
32
32
|
|
|
33
33
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Hover Text Test", () => {
|
|
10
10
|
it("should click Sign In and verify error message", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { ip:
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
// Click on Sign In button using new find() API
|
|
@@ -12,7 +12,7 @@ describe("Provision Installer", () => {
|
|
|
12
12
|
it.skipIf(!isLinux)(
|
|
13
13
|
"should download and install a .deb package on Linux",
|
|
14
14
|
async (context) => {
|
|
15
|
-
const testdriver = TestDriver(context);
|
|
15
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
16
16
|
|
|
17
17
|
// Install bat (a cat clone with syntax highlighting) using provision.installer
|
|
18
18
|
const filePath = await testdriver.provision.installer({
|
|
@@ -30,7 +30,7 @@ describe("Provision Installer", () => {
|
|
|
30
30
|
it.skipIf(!isLinux)(
|
|
31
31
|
"should download a shell script and verify it exists",
|
|
32
32
|
async (context) => {
|
|
33
|
-
const testdriver = TestDriver(context);
|
|
33
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
34
34
|
|
|
35
35
|
// Download a shell script (nvm installer)
|
|
36
36
|
const filePath = await testdriver.provision.installer({
|
|
@@ -7,7 +7,7 @@ describe("Launch VS Code on Linux", () => {
|
|
|
7
7
|
it.skipIf(!isLinux)(
|
|
8
8
|
"should launch VS Code on Debian/Ubuntu",
|
|
9
9
|
async (context) => {
|
|
10
|
-
const testdriver = TestDriver(context);
|
|
10
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
11
11
|
|
|
12
12
|
// provision.vscode() automatically calls ready() and starts dashcam
|
|
13
13
|
await testdriver.provision.vscode();
|
|
@@ -24,7 +24,7 @@ describe("Launch VS Code on Linux", () => {
|
|
|
24
24
|
it.skipIf(!isLinux)(
|
|
25
25
|
"should install and use a VS Code extension",
|
|
26
26
|
async (context) => {
|
|
27
|
-
const testdriver = TestDriver(context);
|
|
27
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP });
|
|
28
28
|
|
|
29
29
|
// Launch VS Code with the Prettier extension installed
|
|
30
30
|
await testdriver.provision.vscode({
|
|
@@ -17,7 +17,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
17
17
|
await client.focusApplication("Google Chrome");
|
|
18
18
|
const password = await client.extract("the password");
|
|
19
19
|
const usernameField = await client.find(
|
|
20
|
-
"
|
|
20
|
+
"username input",
|
|
21
21
|
);
|
|
22
22
|
await usernameField.click();
|
|
23
23
|
await client.type(username);
|
|
@@ -33,7 +33,7 @@ const __dirname = dirname(__filename);
|
|
|
33
33
|
|
|
34
34
|
describe("Match Image Test", () => {
|
|
35
35
|
it.skip("should match shopping cart image and verify empty cart", async (context) => {
|
|
36
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
36
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
37
37
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
38
38
|
|
|
39
39
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Press Keys Test", () => {
|
|
10
10
|
it("should create tabs and navigate using keyboard shortcuts", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
const signInButton = await testdriver.find(
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe.skip("Prompt Test", () => {
|
|
10
10
|
it("should execute AI-driven prompts", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Scroll Keyboard Test", () => {
|
|
10
10
|
it("should navigate to webhamster.com and scroll with keyboard", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
//
|
|
@@ -8,7 +8,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
8
8
|
|
|
9
9
|
describe("Scroll Until Image Test", () => {
|
|
10
10
|
it.skip("should scroll until brown colored house image appears", async (context) => {
|
|
11
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
11
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
12
12
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
13
|
|
|
14
14
|
//
|
|
@@ -15,7 +15,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
15
15
|
await client.focusApplication("Google Chrome");
|
|
16
16
|
const password = await client.extract("the password");
|
|
17
17
|
const usernameField = await client.find(
|
|
18
|
-
"
|
|
18
|
+
"username input",
|
|
19
19
|
);
|
|
20
20
|
await usernameField.click();
|
|
21
21
|
await client.type(username);
|
|
@@ -27,7 +27,7 @@ async function performLogin(client, username = "standard_user") {
|
|
|
27
27
|
|
|
28
28
|
describe("Scroll Until Text Test", () => {
|
|
29
29
|
it('should scroll until "testdriver socks" appears', async (context) => {
|
|
30
|
-
const testdriver = TestDriver(context, {
|
|
30
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
31
31
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
32
32
|
|
|
33
33
|
//
|
|
@@ -10,7 +10,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
10
10
|
|
|
11
11
|
describe("Scroll Test", () => {
|
|
12
12
|
it("should navigate and scroll down the page", async (context) => {
|
|
13
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
14
14
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
15
|
|
|
16
16
|
// Give Chrome a moment to fully render the UI
|
|
@@ -3,7 +3,7 @@ import { TestDriver } from "../../lib/vitest/hooks.mjs";
|
|
|
3
3
|
|
|
4
4
|
describe("Type Test", () => {
|
|
5
5
|
it("should enter standard_user in username field", async (context) => {
|
|
6
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
6
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
7
7
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
8
8
|
|
|
9
9
|
//
|
|
@@ -20,7 +20,7 @@ describe("Type Test", () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
it("should show validation message when clicking Sign In without password", async (context) => {
|
|
23
|
-
const testdriver = TestDriver(context, { headless: true });
|
|
23
|
+
const testdriver = TestDriver(context, { ip: context.ip || process.env.TD_IP, headless: true });
|
|
24
24
|
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
25
25
|
|
|
26
26
|
// First fill in username
|
|
@@ -19,7 +19,7 @@ describe("Windows App Installation", () => {
|
|
|
19
19
|
it.skipIf(isLinux)("should download, install, and launch GitButler on Windows", async (context) => {
|
|
20
20
|
// Alternative approach using provision.installer helper
|
|
21
21
|
const testdriver = TestDriver(context, {
|
|
22
|
-
|
|
22
|
+
ip: context.ip || process.env.TD_IP,
|
|
23
23
|
os: 'windows'
|
|
24
24
|
});
|
|
25
25
|
|
package/vitest.config.mjs
CHANGED
|
@@ -6,6 +6,9 @@ import { defineConfig } from 'vitest/config';
|
|
|
6
6
|
// and to worker processes
|
|
7
7
|
config();
|
|
8
8
|
|
|
9
|
+
// Always include AWS setup - it will be a no-op unless TD_OS=windows
|
|
10
|
+
const setupFiles = ['testdriverai/vitest/setup', 'testdriverai/vitest/setup-aws'];
|
|
11
|
+
|
|
9
12
|
export default defineConfig({
|
|
10
13
|
test: {
|
|
11
14
|
testTimeout: 900000,
|
|
@@ -17,6 +20,6 @@ export default defineConfig({
|
|
|
17
20
|
TestDriver(),
|
|
18
21
|
['junit', { outputFile: 'test-report.junit.xml' }]
|
|
19
22
|
],
|
|
20
|
-
setupFiles
|
|
23
|
+
setupFiles,
|
|
21
24
|
},
|
|
22
25
|
});
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
name: AWS
|
|
2
|
-
on:
|
|
3
|
-
workflow_dispatch:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
paths-ignore:
|
|
8
|
-
- "docs/**"
|
|
9
|
-
pull_request:
|
|
10
|
-
branches:
|
|
11
|
-
- main
|
|
12
|
-
types:
|
|
13
|
-
- ready_for_review
|
|
14
|
-
pull_request_review:
|
|
15
|
-
types:
|
|
16
|
-
- submitted
|
|
17
|
-
|
|
18
|
-
jobs:
|
|
19
|
-
gather:
|
|
20
|
-
name: Gather Test Files
|
|
21
|
-
runs-on: ubuntu-latest
|
|
22
|
-
outputs:
|
|
23
|
-
test_files: ${{ steps.test_list.outputs.files }}
|
|
24
|
-
steps:
|
|
25
|
-
- name: Check out repository
|
|
26
|
-
uses: actions/checkout@v4
|
|
27
|
-
|
|
28
|
-
- name: Find all test files
|
|
29
|
-
id: test_list
|
|
30
|
-
run: |
|
|
31
|
-
FILES=$(ls ./testdriver/acceptance/*.yaml)
|
|
32
|
-
FILENAMES=$(basename -a $FILES)
|
|
33
|
-
FILES_JSON=$(echo "$FILENAMES" | jq -R -s -c 'split("\n")[:-1]')
|
|
34
|
-
echo "files=$FILES_JSON" >> $GITHUB_OUTPUT
|
|
35
|
-
|
|
36
|
-
test:
|
|
37
|
-
needs: gather
|
|
38
|
-
runs-on: ubuntu-latest
|
|
39
|
-
strategy:
|
|
40
|
-
matrix:
|
|
41
|
-
test: ${{ fromJson(needs.gather.outputs.test_files) }}
|
|
42
|
-
fail-fast: false
|
|
43
|
-
steps:
|
|
44
|
-
- name: Checkout repository
|
|
45
|
-
uses: actions/checkout@v4
|
|
46
|
-
with:
|
|
47
|
-
fetch-depth: 0
|
|
48
|
-
# only needed for `act`
|
|
49
|
-
# - name: Install AWS CLI
|
|
50
|
-
# run: |
|
|
51
|
-
# apt-get update
|
|
52
|
-
# apt-get install curl unzip -y
|
|
53
|
-
# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
|
54
|
-
# unzip awscliv2.zip
|
|
55
|
-
# ./aws/install
|
|
56
|
-
- name: Set up Node.js
|
|
57
|
-
uses: actions/setup-node@v4
|
|
58
|
-
with:
|
|
59
|
-
node-version: "20"
|
|
60
|
-
cache: "npm"
|
|
61
|
-
- name: Install dependencies
|
|
62
|
-
run: NODE_ENV=production npm ci
|
|
63
|
-
- name: Setup AWS Instance
|
|
64
|
-
id: aws-setup
|
|
65
|
-
run: |
|
|
66
|
-
chmod +x ./setup/aws/spawn-runner.sh
|
|
67
|
-
OUTPUT=$(./setup/aws/spawn-runner.sh | tee /dev/stderr) # Capture and display output
|
|
68
|
-
echo "$OUTPUT"
|
|
69
|
-
PUBLIC_IP=$(echo "$OUTPUT" | grep "PUBLIC_IP=" | cut -d'=' -f2)
|
|
70
|
-
INSTANCE_ID=$(echo "$OUTPUT" | grep "INSTANCE_ID=" | cut -d'=' -f2)
|
|
71
|
-
AWS_REGION=$(echo "$OUTPUT" | grep "AWS_REGION=" | cut -d'=' -f2)
|
|
72
|
-
echo "public-ip=$PUBLIC_IP" >> $GITHUB_OUTPUT
|
|
73
|
-
echo "instance-id=$INSTANCE_ID" >> $GITHUB_OUTPUT
|
|
74
|
-
echo "aws-region=$AWS_REGION" >> $GITHUB_OUTPUT
|
|
75
|
-
env:
|
|
76
|
-
FORCE_COLOR: 3
|
|
77
|
-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
78
|
-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
79
|
-
AWS_REGION: us-east-2
|
|
80
|
-
AWS_LAUNCH_TEMPLATE_ID: lt-00d02f31cfc602f27
|
|
81
|
-
AMI_ID: ami-0c2858680200ac890
|
|
82
|
-
RESOLUTION: 1920x1080
|
|
83
|
-
- name: Run TestDriver
|
|
84
|
-
run: node bin/testdriverai.js run testdriver/acceptance/${{ matrix.test }} --ip="${{ steps.aws-setup.outputs.public-ip }}" --junit=out.xml
|
|
85
|
-
env:
|
|
86
|
-
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
87
|
-
TD_WEBSITE: https://testdriver-sandbox.vercel.app
|
|
88
|
-
TD_THIS_FILE: ${{ matrix.test }}
|
|
89
|
-
- name: Upload TestDriver AI CLI logs
|
|
90
|
-
if: always()
|
|
91
|
-
uses: actions/upload-artifact@v4
|
|
92
|
-
with:
|
|
93
|
-
name: testdriverai-cli-logs-${{ matrix.test }}
|
|
94
|
-
path: /tmp/testdriverai-cli-*.log
|
|
95
|
-
if-no-files-found: warn
|
|
96
|
-
retention-days: 30
|
|
97
|
-
- name: Upload test results as artifact
|
|
98
|
-
if: always()
|
|
99
|
-
uses: actions/upload-artifact@v4
|
|
100
|
-
with:
|
|
101
|
-
name: test-results-${{ matrix.test }}
|
|
102
|
-
path: out.xml
|
|
103
|
-
retention-days: 30
|
|
104
|
-
- name: Shutdown AWS Instance
|
|
105
|
-
if: always()
|
|
106
|
-
run: aws ec2 terminate-instances --region "$AWS_REGION" --instance-ids "$INSTANCE_ID"
|
|
107
|
-
env:
|
|
108
|
-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
|
109
|
-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
110
|
-
AWS_REGION: ${{ steps.aws-setup.outputs.aws-region }}
|
|
111
|
-
INSTANCE_ID: ${{ steps.aws-setup.outputs.instance-id }}
|