Skip to content

Commit 0b79426

Browse files
committed
improve playwright tests
1 parent 50a0792 commit 0b79426

10 files changed

Lines changed: 121 additions & 65 deletions

File tree

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@
2727
"overrides": {
2828
"cookie": "^0.7.2",
2929
"cross-spawn": "^7.0.5"
30-
}
30+
},
31+
"ignoredBuiltDependencies": [
32+
"ssh2"
33+
],
34+
"onlyBuiltDependencies": [
35+
"@firebase/util",
36+
"@sentry/cli",
37+
"@tailwindcss/oxide",
38+
"cpu-features",
39+
"esbuild",
40+
"lefthook",
41+
"protobufjs"
42+
]
3143
}
3244
}

packages/app-builder/src/routes/_auth+/sign-in.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
2828
const [err, appConfig] = await tryit(() => appConfigRepository.getAppConfig())();
2929

3030
if (err) {
31-
console.error('Error fetching app config API');
31+
console.error('Error fetching app config API', err);
3232
}
3333

3434
const url = new URL(request.url);

packages/tests/auth.json

Lines changed: 59 additions & 14 deletions
Large diffs are not rendered by default.

packages/tests/e2e/auth.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { fileURLToPath } from 'url';
44

55
test('Initial login page', async ({ page }) => {
66
await page.goto('/');
7-
await page.waitForURL('/sign-in');
7+
await page.waitForURL('/sign-in-email?email=');
88

99
await expect(page).toHaveTitle('Marble');
10-
await expect(page.getByText('Great rules are built with the Right Tools')).toBeVisible();
10+
await expect(page.getByText('Iterate. Improve. Automate.')).toBeVisible();
1111
});
1212

1313
test('Invalid username', async ({ page }) => {
@@ -23,7 +23,7 @@ test('Invalid username', async ({ page }) => {
2323
.fill('very-secret');
2424
await page.getByRole('button', { name: 'Sign in', exact: true }).click();
2525

26-
await expect(page.getByText('No user account found for this address.')).toBeVisible();
26+
await expect(page.getByText('Invalid login credentials.')).toBeVisible();
2727
});
2828

2929
test('Invalid password', async ({ page }) => {
@@ -39,7 +39,7 @@ test('Invalid password', async ({ page }) => {
3939
.fill('invalid');
4040
await page.getByRole('button', { name: 'Sign in', exact: true }).click();
4141

42-
await expect(page.getByText('Wrong password.')).toBeVisible();
42+
await expect(page.getByText('Invalid login credentials.')).toBeVisible();
4343
});
4444

4545
const authState = path.join(path.dirname(fileURLToPath(import.meta.url)), '../auth.json');

packages/tests/e2e/custom-lists.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { waitForThen } from 'tests/common/utils';
44

55
test('Create new list', async ({ page }) => {
66
await page.goto('/lists');
7-
7+
88
const listName = crypto.randomUUID();
99
const values = Array.from({ length: 5 }, () => crypto.randomUUID());
1010

@@ -21,10 +21,11 @@ test('Create new list', async ({ page }) => {
2121
await page.waitForURL('/lists/**');
2222
await page.waitForLoadState();
2323

24-
2524
for (const value of values) {
26-
await waitForThen(page, page.getByRole('button', { name: 'New value' }), async (button) =>
27-
await button.click(),
25+
await waitForThen(
26+
page,
27+
page.getByRole('button', { name: 'New value' }),
28+
async (button) => await button.click(),
2829
);
2930

3031
await waitForThen(

packages/tests/e2e/fixtures.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
import knex from 'knex';
21
import crypto from 'crypto';
2+
import knex from 'knex';
33

4-
interface Org { id: string; }
4+
interface Org {
5+
id: string;
6+
}
57

68
interface Table {
79
table: string;
8-
fields: { [key: string]: string};
10+
fields: { [key: string]: string };
911
}
1012

1113
const TABLES: Table[] = [
1214
{
1315
table: 'transactions',
1416
fields: {
15-
'beneficiary': 'String',
16-
'amount': 'Float',
17-
}
18-
}
19-
]
17+
beneficiary: 'String',
18+
amount: 'Float',
19+
},
20+
},
21+
];
2022

2123
export const setupFixtures = async (dsn: string, apiUrl: string) => {
2224
const sql = knex({ client: 'pg', connection: dsn });
@@ -26,10 +28,10 @@ export const setupFixtures = async (dsn: string, apiUrl: string) => {
2628
const hash = crypto.createHash('sha256').update(apiKey).digest();
2729

2830
await sql('api_keys').insert({
29-
'org_id': org!.id,
30-
'role': 4,
31-
'prefix': apiKey.substring(0, 3),
32-
'key_hash': hash,
31+
org_id: org!.id,
32+
role: 4,
33+
prefix: apiKey.substring(0, 3),
34+
key_hash: hash,
3335
});
3436

3537
apiUrl = `http://localhost:${apiUrl}`;
@@ -45,12 +47,12 @@ const createTable = async (apiUrl: string, apiKey: string, table: Table) => {
4547
headers: {
4648
'x-api-key': apiKey,
4749
},
48-
body: JSON.stringify({ 'name': table.table, 'description': 'Lorem ipsum.' })
50+
body: JSON.stringify({ name: table.table, description: 'Lorem ipsum.' }),
4951
});
5052

5153
if (tableResponse.status != 200) throw new Error('failed to create data model table');
5254

53-
const tableId = (await tableResponse.json() as { id: string; }).id;
55+
const tableId = ((await tableResponse.json()) as { id: string }).id;
5456

5557
for (const [fieldName, fieldType] of Object.entries(table.fields)) {
5658
const fieldResponse = await fetch(`${apiUrl}/data-model/tables/${tableId}/fields`, {
@@ -59,11 +61,11 @@ const createTable = async (apiUrl: string, apiKey: string, table: Table) => {
5961
'x-api-key': apiKey,
6062
},
6163
body: JSON.stringify({
62-
'name': fieldName,
63-
'type': fieldType,
64+
name: fieldName,
65+
type: fieldType,
6466
}),
6567
});
6668

6769
if (fieldResponse.status != 200) throw new Error('failed to create data model table field');
6870
}
69-
}
71+
};
Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
import { test, expect } from '@playwright/test';
1+
import { expect, test } from '@playwright/test';
22
import crypto from 'crypto';
33
import { waitForThen } from 'tests/common/utils';
44

55
test('Create a simple scenario', async ({ page }) => {
66
await page.goto('/scenarios');
7-
7+
88
const scenarioName = crypto.randomUUID();
99

1010
await page.getByRole('button', { name: 'New Scenario' }).click();
1111

1212
await waitForThen(
1313
page,
1414
page.getByRole('textbox', { name: 'Name' }),
15-
async (field) => await field.fill(scenarioName),
15+
async (field) => await field.fill(scenarioName),
1616
);
1717

1818
await page.getByRole('textbox', { name: 'Description' }).fill('DESC');
1919

20-
await waitForThen(
21-
page,
22-
page.getByRole('combobox'),
23-
async (box) => await box.click(),
24-
);
20+
await waitForThen(page, page.getByRole('combobox'), async (box) => await box.click());
2521

2622
await page.waitForTimeout(200);
2723

@@ -43,11 +39,11 @@ test('Create a simple scenario', async ({ page }) => {
4339
await page.getByRole('button', { name: 'Select an operand...' }).first().click();
4440
await page.getByRole('option', { name: 'transactions' }).hover();
4541
await page.getByText('amount').click();
46-
await page.getByRole('combobox').click();
42+
await page.getByRole('button', { name: '...' }).first().click();
4743
await page.getByRole('option', { name: '>' }).click();
4844
await page.getByRole('button', { name: 'Select an operand...' }).click();
49-
await page.getByRole('combobox', { name: 'Select or create an operand' }).fill('100');
50-
await page.getByRole('combobox', { name: 'Select or create an operand' }).press('Enter');
45+
await page.getByPlaceholder('Select or create an operand').fill('100');
46+
await page.getByPlaceholder('Select or create an operand').press('Enter');
5147
await page.getByRole('button', { name: 'Save' }).click();
5248
await page.getByRole('link', { name: 'Rules' }).click();
5349
await page.getByRole('button', { name: 'Add' }).click();
@@ -56,21 +52,23 @@ test('Create a simple scenario', async ({ page }) => {
5652
await page.getByRole('button', { name: 'Select an operand...' }).first().click();
5753
await page.getByRole('option', { name: 'transactions' }).hover();
5854
await page.getByText('amount').click();
59-
await page.getByRole('combobox').click();
55+
await page.getByRole('button', { name: '...' }).first().click();
6056
await page.getByRole('option', { name: '>' }).click();
6157
await page.getByRole('button', { name: 'Select an operand...' }).click();
62-
await page.getByRole('combobox', { name: 'Select or create an operand' }).fill('9000');
63-
await page.getByRole('combobox', { name: 'Select or create an operand' }).press('Enter');
58+
await page.getByPlaceholder('Select or create an operand').fill('9000');
59+
await page.getByPlaceholder('Select or create an operand').press('Enter');
6460
await page.getByRole('button', { name: 'Save' }).click();
6561

6662
await page.getByRole('listitem').filter({ hasText: 'Scenarios' }).getByRole('link').click();
6763

68-
await expect(page.getByRole('link', { name: `${scenarioName} DESC`})).toBeVisible();
64+
await expect(page.getByRole('link', { name: `${scenarioName} DESC` })).toBeVisible();
6965

7066
await page.getByRole('link', { name: `${scenarioName} DESC` }).click();
7167
await page.getByRole('link', { name: 'draft' }).click();
7268

73-
await expect(page.getByRole('button', { name: 'edit_operand.operator_type.' })).toHaveText('amount');
74-
await expect(page.getByRole('combobox')).toHaveText('>');
69+
await expect(page.getByRole('button', { name: 'edit_operand.operator_type.' })).toHaveText(
70+
'amount',
71+
);
72+
await expect(page.getByRole('button', { name: '>' })).toHaveText('>');
7573
await expect(page.getByRole('button', { name: 'Number 100' })).toBeVisible();
76-
});
74+
});

packages/tests/e2e/setup.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ async function globalSetup() {
2020
.start();
2121

2222
const dsn = 'postgres://postgres:marble@db/marble?sslmode=disable';
23-
const externalDsn = `postgres://postgres:marble@${db.getIpAddress(net.getName())}/marble?sslmode=disable`;
23+
const externalDsn = `postgres://postgres:marble@127.0.0.1:${db.getFirstMappedPort()}/marble?sslmode=disable`;
2424

2525
const firebase = await new GenericContainer(
2626
'europe-west1-docker.pkg.dev/marble-infra/marble/firebase-emulator:latest',
@@ -43,7 +43,6 @@ async function globalSetup() {
4343
.withDefaultLogDriver()
4444
.start();
4545

46-
4746
const api = await new GenericContainer(
4847
'europe-west1-docker.pkg.dev/marble-infra/marble/marble-backend',
4948
)
@@ -54,6 +53,7 @@ async function globalSetup() {
5453
PG_CONNECTION_STRING: dsn,
5554
MARBLE_APP_URL: 'http://localhost:3000',
5655
FIREBASE_AUTH_EMULATOR_HOST: `firebase:9099`,
56+
FIREBASE_API_KEY: 'dummy',
5757
GOOGLE_CLOUD_PROJECT: 'test-project',
5858
CREATE_GLOBAL_ADMIN_EMAIL: 'admin@checkmarble.com',
5959
CREATE_ORG_NAME: 'Zorg',
@@ -65,7 +65,6 @@ async function globalSetup() {
6565
.withDefaultLogDriver()
6666
.start();
6767

68-
6968
process.env['API_PORT'] = api.getFirstMappedPort().toString();
7069
process.env['FIREBASE_PORT'] = firebase.getFirstMappedPort().toString();
7170

packages/tests/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"sideEffect": false,
66
"type": "module",
77
"scripts": {
8+
"test:install": "playwright install",
89
"test": "NODE_OPTIONS=--disable-warning=ExperimentalWarning playwright test",
910
"test:ui": "NODE_OPTIONS=--disable-warning=ExperimentalWarning playwright test --ui",
1011
"lint": "eslint ."

packages/tests/playwright.config.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default defineConfig({
1616
screenshot: 'only-on-failure',
1717
launchOptions: {
1818
slowMo: 250,
19-
}
19+
},
2020
},
2121
projects: [
2222
{
@@ -48,8 +48,6 @@ export default defineConfig({
4848
MARBLE_API_URL_SERVER: `http://localhost:${process.env['API_PORT']}`,
4949
MARBLE_API_URL_CLIENT: `http://localhost:${process.env['API_PORT']}`,
5050
FIREBASE_AUTH_EMULATOR_HOST: `localhost:${process.env['FIREBASE_PORT']}`,
51-
FIREBASE_API_KEY: 'dummy',
52-
FIREBASE_PROJECT_ID: 'test-project',
5351
},
5452
},
5553
});

0 commit comments

Comments
 (0)