@tramvai/test-pw 4.36.2 → 4.38.0
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 +57 -0
- package/lib/fixtures/build-app.d.ts +53 -0
- package/lib/fixtures/build-app.es.js +86 -0
- package/lib/fixtures/build-app.js +98 -0
- package/lib/fixtures/start-app.d.ts +2 -10
- package/lib/fixtures/types.d.ts +11 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.es.js +1 -0
- package/lib/index.js +3 -0
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -95,3 +95,60 @@ test.describe('examples/app', async () => {
|
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
You can find more info about `app` object in our [Testing Guide](guides/testing.md#integration-tests)
|
|
98
|
+
|
|
99
|
+
### Production build testing
|
|
100
|
+
|
|
101
|
+
If you need to test production build, `@tramvai/test-pw` provide a few fixtures for it:
|
|
102
|
+
- `appServerFixture` to run compiled application server
|
|
103
|
+
- `buildAppFixture` to run production build of the application (will be called implicitly for `appServerFixture`)
|
|
104
|
+
|
|
105
|
+
First, configure fixtures:
|
|
106
|
+
|
|
107
|
+
```ts title="__integration__/test-fixture.ts"
|
|
108
|
+
import path from 'path';
|
|
109
|
+
import { test as base } from '@playwright/test';
|
|
110
|
+
import type { BuildAppTypes } from '@tramvai/test-pw';
|
|
111
|
+
import { appServerFixture } from '@tramvai/test-pw';
|
|
112
|
+
|
|
113
|
+
type TestFixture = {};
|
|
114
|
+
|
|
115
|
+
type WorkerFixture = {
|
|
116
|
+
app: BuildAppTypes.TestApp;
|
|
117
|
+
appTarget: BuildAppTypes.AppTarget;
|
|
118
|
+
buildOptions: BuildAppTypes.StartOptions;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const test = base.extend<TestFixture, WorkerFixture>({
|
|
122
|
+
appTarget: [
|
|
123
|
+
// provide application name and directory
|
|
124
|
+
{
|
|
125
|
+
target: 'appName',
|
|
126
|
+
cwd: path.resolve(__dirname, '..'),
|
|
127
|
+
},
|
|
128
|
+
{ scope: 'worker', auto: true, option: true },
|
|
129
|
+
],
|
|
130
|
+
// any `buildCli` parameters
|
|
131
|
+
buildOptions: [{
|
|
132
|
+
env: {
|
|
133
|
+
SOME_MOCKED_API: 'xxx'
|
|
134
|
+
},
|
|
135
|
+
}, { scope: 'worker', auto: true, option: true }],
|
|
136
|
+
|
|
137
|
+
appServer: appServerFixture,
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Then, use the `appServer` object in integration tests:
|
|
142
|
+
|
|
143
|
+
```ts title="__integration__/appName.integration.ts"
|
|
144
|
+
import { expect } from '@playwright/test';
|
|
145
|
+
import { test } from './test-fixture';
|
|
146
|
+
|
|
147
|
+
test.describe('examples/app', async () => {
|
|
148
|
+
test('Navigation is visible', async ({ appServer, page }) => {
|
|
149
|
+
await page.goto(`http://localhost:${appServer.port}/`);
|
|
150
|
+
|
|
151
|
+
expect(page.getByRole('navigation')).toBeVisible();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { WorkerFixture, TestFixture } from '@playwright/test';
|
|
2
|
+
import type { BuildCliOptions } from '@tramvai/test-integration';
|
|
3
|
+
import type { AppTarget as _AppTarget } from './types';
|
|
4
|
+
export type AppServerType = {
|
|
5
|
+
port: number;
|
|
6
|
+
staticPort: number;
|
|
7
|
+
};
|
|
8
|
+
export type AppServerOptionsType = {
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
output?: {
|
|
11
|
+
client?: string;
|
|
12
|
+
server?: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare namespace BuildAppTypes {
|
|
16
|
+
type Cwd = string;
|
|
17
|
+
type AppTarget = _AppTarget;
|
|
18
|
+
type BuildOptions = BuildCliOptions;
|
|
19
|
+
type AppServer = AppServerType;
|
|
20
|
+
type AppServerOptions = AppServerOptionsType;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Фикстура запускает сборку приложения с помощью метода `buildCli` из `@tramvai/test-integration`
|
|
24
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
25
|
+
* @param buildOptions дополнительные параметры метода `buildCli` (например билдтайм env переменные)
|
|
26
|
+
*/
|
|
27
|
+
export declare const buildAppFixture: [
|
|
28
|
+
WorkerFixture<void, {
|
|
29
|
+
appTarget: BuildAppTypes.AppTarget;
|
|
30
|
+
buildOptions?: BuildAppTypes.BuildOptions;
|
|
31
|
+
}>,
|
|
32
|
+
{
|
|
33
|
+
scope: 'worker';
|
|
34
|
+
timeout: number;
|
|
35
|
+
}
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* Фикстура запускает собранное с помощью `buildAppFixture` приложение (а именно server.js)
|
|
39
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
40
|
+
* @param appServerOptions дополнительные параметры для приложения (например рантайм env переменные)
|
|
41
|
+
* @returns возвращает свойства запущенного сервера (порт приложения, порт по которому доступны ассеты)
|
|
42
|
+
*/
|
|
43
|
+
export declare const appServerFixture: [
|
|
44
|
+
TestFixture<BuildAppTypes.AppServer, {
|
|
45
|
+
appTarget: BuildAppTypes.AppTarget;
|
|
46
|
+
appServerOptions: BuildAppTypes.AppServerOptions;
|
|
47
|
+
buildApp: void;
|
|
48
|
+
}>,
|
|
49
|
+
{
|
|
50
|
+
scope: 'test';
|
|
51
|
+
}
|
|
52
|
+
];
|
|
53
|
+
//# sourceMappingURL=build-app.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import mergeDeep from '@tinkoff/utils/object/mergeDeep';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { node } from 'execa';
|
|
4
|
+
import waitOn from 'wait-on';
|
|
5
|
+
import getPort from 'get-port';
|
|
6
|
+
import { buildCli } from '@tramvai/test-integration';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Фикстура запускает сборку приложения с помощью метода `buildCli` из `@tramvai/test-integration`
|
|
10
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
11
|
+
* @param buildOptions дополнительные параметры метода `buildCli` (например билдтайм env переменные)
|
|
12
|
+
*/
|
|
13
|
+
const buildAppFixture = [
|
|
14
|
+
async ({ appTarget, buildOptions }, use) => {
|
|
15
|
+
var _a;
|
|
16
|
+
await buildCli('target' in appTarget
|
|
17
|
+
? appTarget.target
|
|
18
|
+
: mergeDeep(appTarget.config, {
|
|
19
|
+
name: appTarget.name,
|
|
20
|
+
type: 'application',
|
|
21
|
+
root: appTarget.cwd,
|
|
22
|
+
}), {
|
|
23
|
+
...buildOptions,
|
|
24
|
+
rootDir: (_a = appTarget.cwd) !== null && _a !== void 0 ? _a : path.dirname(path.resolve(module.parent.filename, '.')),
|
|
25
|
+
});
|
|
26
|
+
await use();
|
|
27
|
+
// @todo clear dist?
|
|
28
|
+
},
|
|
29
|
+
{ scope: 'worker', timeout: 60000 },
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Фикстура запускает собранное с помощью `buildAppFixture` приложение (а именно server.js)
|
|
33
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
34
|
+
* @param appServerOptions дополнительные параметры для приложения (например рантайм env переменные)
|
|
35
|
+
* @returns возвращает свойства запущенного сервера (порт приложения, порт по которому доступны ассеты)
|
|
36
|
+
*/
|
|
37
|
+
const appServerFixture = [
|
|
38
|
+
async ({ appTarget, appServerOptions, buildApp }, use) => {
|
|
39
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
40
|
+
const { env = {}, output = {} } = appServerOptions;
|
|
41
|
+
const root = (_a = appTarget.cwd) !== null && _a !== void 0 ? _a : path.dirname(path.resolve(module.parent.filename, '.'));
|
|
42
|
+
const port = await getPort();
|
|
43
|
+
const staticPort = await getPort();
|
|
44
|
+
const readinessProbePath = `http://localhost:${port}/readyz`;
|
|
45
|
+
const clientOutput = (_b = output.client) !== null && _b !== void 0 ? _b : path.join('dist', 'client');
|
|
46
|
+
const serverOutput = (_c = output.server) !== null && _c !== void 0 ? _c : path.join('dist', 'server');
|
|
47
|
+
const server = node(path.resolve(root, serverOutput, 'server.js'), [], {
|
|
48
|
+
cwd: root,
|
|
49
|
+
env: {
|
|
50
|
+
PORT: String(port),
|
|
51
|
+
PORT_STATIC: String(staticPort),
|
|
52
|
+
NODE_ENV: 'production',
|
|
53
|
+
CACHE_WARMUP_DISABLED: 'true',
|
|
54
|
+
DEV_STATIC: 'true',
|
|
55
|
+
ASSETS_PREFIX: `http://localhost:${staticPort}/${clientOutput}/`,
|
|
56
|
+
...env,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
// playwright can only collect string-form stdio into the test report
|
|
60
|
+
// https://github.com/microsoft/playwright/issues/23993
|
|
61
|
+
(_d = server.stdout) === null || _d === void 0 ? void 0 : _d.setEncoding('utf-8');
|
|
62
|
+
(_e = server.stderr) === null || _e === void 0 ? void 0 : _e.setEncoding('utf-8');
|
|
63
|
+
// @todo pipe only when server run is failed
|
|
64
|
+
(_f = server.stdout) === null || _f === void 0 ? void 0 : _f.pipe(process.stdout);
|
|
65
|
+
(_g = server.stderr) === null || _g === void 0 ? void 0 : _g.pipe(process.stderr);
|
|
66
|
+
await Promise.race([
|
|
67
|
+
server,
|
|
68
|
+
waitOn({
|
|
69
|
+
resources: [readinessProbePath],
|
|
70
|
+
delay: 100,
|
|
71
|
+
interval: 100,
|
|
72
|
+
timeout: 5 * 1000,
|
|
73
|
+
validateStatus: (status) => status === 200,
|
|
74
|
+
}),
|
|
75
|
+
]);
|
|
76
|
+
const app = {
|
|
77
|
+
port,
|
|
78
|
+
staticPort,
|
|
79
|
+
};
|
|
80
|
+
await use(app);
|
|
81
|
+
server.kill('SIGKILL');
|
|
82
|
+
},
|
|
83
|
+
{ scope: 'test' },
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
export { appServerFixture, buildAppFixture };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var mergeDeep = require('@tinkoff/utils/object/mergeDeep');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var execa = require('execa');
|
|
8
|
+
var waitOn = require('wait-on');
|
|
9
|
+
var getPort = require('get-port');
|
|
10
|
+
var testIntegration = require('@tramvai/test-integration');
|
|
11
|
+
|
|
12
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
13
|
+
|
|
14
|
+
var mergeDeep__default = /*#__PURE__*/_interopDefaultLegacy(mergeDeep);
|
|
15
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
16
|
+
var waitOn__default = /*#__PURE__*/_interopDefaultLegacy(waitOn);
|
|
17
|
+
var getPort__default = /*#__PURE__*/_interopDefaultLegacy(getPort);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Фикстура запускает сборку приложения с помощью метода `buildCli` из `@tramvai/test-integration`
|
|
21
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
22
|
+
* @param buildOptions дополнительные параметры метода `buildCli` (например билдтайм env переменные)
|
|
23
|
+
*/
|
|
24
|
+
const buildAppFixture = [
|
|
25
|
+
async ({ appTarget, buildOptions }, use) => {
|
|
26
|
+
var _a;
|
|
27
|
+
await testIntegration.buildCli('target' in appTarget
|
|
28
|
+
? appTarget.target
|
|
29
|
+
: mergeDeep__default["default"](appTarget.config, {
|
|
30
|
+
name: appTarget.name,
|
|
31
|
+
type: 'application',
|
|
32
|
+
root: appTarget.cwd,
|
|
33
|
+
}), {
|
|
34
|
+
...buildOptions,
|
|
35
|
+
rootDir: (_a = appTarget.cwd) !== null && _a !== void 0 ? _a : path__default["default"].dirname(path__default["default"].resolve(module.parent.filename, '.')),
|
|
36
|
+
});
|
|
37
|
+
await use();
|
|
38
|
+
// @todo clear dist?
|
|
39
|
+
},
|
|
40
|
+
{ scope: 'worker', timeout: 60000 },
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* Фикстура запускает собранное с помощью `buildAppFixture` приложение (а именно server.js)
|
|
44
|
+
* @param appTarget указывает какое приложение запускать (может как указывать на существующее приложение с tramvai.json конфигом так и принимать полный конфиг)
|
|
45
|
+
* @param appServerOptions дополнительные параметры для приложения (например рантайм env переменные)
|
|
46
|
+
* @returns возвращает свойства запущенного сервера (порт приложения, порт по которому доступны ассеты)
|
|
47
|
+
*/
|
|
48
|
+
const appServerFixture = [
|
|
49
|
+
async ({ appTarget, appServerOptions, buildApp }, use) => {
|
|
50
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
51
|
+
const { env = {}, output = {} } = appServerOptions;
|
|
52
|
+
const root = (_a = appTarget.cwd) !== null && _a !== void 0 ? _a : path__default["default"].dirname(path__default["default"].resolve(module.parent.filename, '.'));
|
|
53
|
+
const port = await getPort__default["default"]();
|
|
54
|
+
const staticPort = await getPort__default["default"]();
|
|
55
|
+
const readinessProbePath = `http://localhost:${port}/readyz`;
|
|
56
|
+
const clientOutput = (_b = output.client) !== null && _b !== void 0 ? _b : path__default["default"].join('dist', 'client');
|
|
57
|
+
const serverOutput = (_c = output.server) !== null && _c !== void 0 ? _c : path__default["default"].join('dist', 'server');
|
|
58
|
+
const server = execa.node(path__default["default"].resolve(root, serverOutput, 'server.js'), [], {
|
|
59
|
+
cwd: root,
|
|
60
|
+
env: {
|
|
61
|
+
PORT: String(port),
|
|
62
|
+
PORT_STATIC: String(staticPort),
|
|
63
|
+
NODE_ENV: 'production',
|
|
64
|
+
CACHE_WARMUP_DISABLED: 'true',
|
|
65
|
+
DEV_STATIC: 'true',
|
|
66
|
+
ASSETS_PREFIX: `http://localhost:${staticPort}/${clientOutput}/`,
|
|
67
|
+
...env,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
// playwright can only collect string-form stdio into the test report
|
|
71
|
+
// https://github.com/microsoft/playwright/issues/23993
|
|
72
|
+
(_d = server.stdout) === null || _d === void 0 ? void 0 : _d.setEncoding('utf-8');
|
|
73
|
+
(_e = server.stderr) === null || _e === void 0 ? void 0 : _e.setEncoding('utf-8');
|
|
74
|
+
// @todo pipe only when server run is failed
|
|
75
|
+
(_f = server.stdout) === null || _f === void 0 ? void 0 : _f.pipe(process.stdout);
|
|
76
|
+
(_g = server.stderr) === null || _g === void 0 ? void 0 : _g.pipe(process.stderr);
|
|
77
|
+
await Promise.race([
|
|
78
|
+
server,
|
|
79
|
+
waitOn__default["default"]({
|
|
80
|
+
resources: [readinessProbePath],
|
|
81
|
+
delay: 100,
|
|
82
|
+
interval: 100,
|
|
83
|
+
timeout: 5 * 1000,
|
|
84
|
+
validateStatus: (status) => status === 200,
|
|
85
|
+
}),
|
|
86
|
+
]);
|
|
87
|
+
const app = {
|
|
88
|
+
port,
|
|
89
|
+
staticPort,
|
|
90
|
+
};
|
|
91
|
+
await use(app);
|
|
92
|
+
server.kill('SIGKILL');
|
|
93
|
+
},
|
|
94
|
+
{ scope: 'test' },
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
exports.appServerFixture = appServerFixture;
|
|
98
|
+
exports.buildAppFixture = buildAppFixture;
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import type { WorkerFixture } from '@playwright/test';
|
|
2
2
|
import type { StartCliOptions, StartCliResult } from '@tramvai/test-integration';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AppTarget as _AppTarget } from './types';
|
|
4
4
|
export declare namespace StartAppTypes {
|
|
5
5
|
type TestApp = StartCliResult;
|
|
6
|
-
type AppTarget = {
|
|
7
|
-
name: string;
|
|
8
|
-
cwd: string;
|
|
9
|
-
config?: Partial<ConvertToSchema<ApplicationConfigEntry>>;
|
|
10
|
-
} | {
|
|
11
|
-
target: string;
|
|
12
|
-
cwd: string;
|
|
13
|
-
name?: string;
|
|
14
|
-
};
|
|
15
6
|
type StartOptions = StartCliOptions;
|
|
7
|
+
type AppTarget = _AppTarget;
|
|
16
8
|
}
|
|
17
9
|
/**
|
|
18
10
|
* Фикстура запускает приложение с помощью метода `startCli` из `@tramvai/test-integration`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ApplicationConfigEntry, ConvertToSchema } from '@tramvai/cli';
|
|
2
|
+
export type AppTarget = {
|
|
3
|
+
name: string;
|
|
4
|
+
cwd: string;
|
|
5
|
+
config?: Partial<ConvertToSchema<ApplicationConfigEntry>>;
|
|
6
|
+
} | {
|
|
7
|
+
target: string;
|
|
8
|
+
cwd: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
package/lib/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { wrapPlaywrightPage } from './wrapper';
|
|
|
5
5
|
export * from './utils';
|
|
6
6
|
export { createPlaywrightConfig } from './config';
|
|
7
7
|
export { startAppFixture, StartAppTypes } from './fixtures/start-app';
|
|
8
|
+
export { buildAppFixture, appServerFixture, BuildAppTypes } from './fixtures/build-app';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.es.js
CHANGED
|
@@ -5,3 +5,4 @@ export { wrapPlaywrightPage } from './wrapper.es.js';
|
|
|
5
5
|
export { waitHydrated } from './utils.es.js';
|
|
6
6
|
export { createPlaywrightConfig } from './config.es.js';
|
|
7
7
|
export { startAppFixture } from './fixtures/start-app.es.js';
|
|
8
|
+
export { appServerFixture, buildAppFixture } from './fixtures/build-app.es.js';
|
package/lib/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var wrapper = require('./wrapper.js');
|
|
|
9
9
|
var utils = require('./utils.js');
|
|
10
10
|
var config = require('./config.js');
|
|
11
11
|
var startApp = require('./fixtures/start-app.js');
|
|
12
|
+
var buildApp = require('./fixtures/build-app.js');
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
|
|
@@ -18,6 +19,8 @@ exports.wrapPlaywrightPage = wrapper.wrapPlaywrightPage;
|
|
|
18
19
|
exports.waitHydrated = utils.waitHydrated;
|
|
19
20
|
exports.createPlaywrightConfig = config.createPlaywrightConfig;
|
|
20
21
|
exports.startAppFixture = startApp.startAppFixture;
|
|
22
|
+
exports.appServerFixture = buildApp.appServerFixture;
|
|
23
|
+
exports.buildAppFixture = buildApp.buildAppFixture;
|
|
21
24
|
Object.keys(playwrightCore).forEach(function (k) {
|
|
22
25
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
23
26
|
enumerable: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/test-pw",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.38.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -18,12 +18,15 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@tinkoff/utils": "^2.1.2",
|
|
21
|
-
"@tramvai/test-integration": "4.
|
|
22
|
-
"@tramvai/tokens-router": "4.
|
|
21
|
+
"@tramvai/test-integration": "4.38.0",
|
|
22
|
+
"@tramvai/tokens-router": "4.38.0",
|
|
23
23
|
"console-with-style": "^1.1.0",
|
|
24
|
+
"get-port": "^5.1.1",
|
|
24
25
|
"supports-color": "8.1.1",
|
|
25
26
|
"env-ci": "^5.0.2",
|
|
26
|
-
"
|
|
27
|
+
"execa": "^5.1.1",
|
|
28
|
+
"tslib": "^2.4.0",
|
|
29
|
+
"wait-on": "^5.3.0"
|
|
27
30
|
},
|
|
28
31
|
"peerDependencies": {
|
|
29
32
|
"playwright-core": "*"
|
|
@@ -31,7 +34,8 @@
|
|
|
31
34
|
"devDependencies": {
|
|
32
35
|
"@types/supports-color": "^8.1.1",
|
|
33
36
|
"@types/env-ci": "^3.1.0",
|
|
34
|
-
"@
|
|
37
|
+
"@types/wait-on": "^5.2.0",
|
|
38
|
+
"@tramvai/cli": "4.38.0",
|
|
35
39
|
"@playwright/test": "1.29.0",
|
|
36
40
|
"playwright-core": "1.29.0"
|
|
37
41
|
},
|