@tachybase/test 0.23.8

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.
Files changed (50) hide show
  1. package/.turbo/turbo-build.log +24 -0
  2. package/LICENSE +201 -0
  3. package/client.d.ts +1 -0
  4. package/client.js +1 -0
  5. package/e2e.d.ts +1 -0
  6. package/e2e.js +1 -0
  7. package/es/client/index.d.ts +7 -0
  8. package/es/client/index.mjs +20 -0
  9. package/es/e2e/defineConfig.d.ts +2 -0
  10. package/es/e2e/e2eUtils.d.ts +298 -0
  11. package/es/e2e/index.d.ts +3 -0
  12. package/es/e2e/index.mjs +20547 -0
  13. package/es/e2e/templatesOfCollection.d.ts +41 -0
  14. package/es/e2e/templatesOfPage.d.ts +573 -0
  15. package/es/index.d.ts +1 -0
  16. package/es/index.mjs +223 -0
  17. package/es/scripts/test-db-creator.d.ts +1 -0
  18. package/es/scripts/test-db-distributor.d.ts +1 -0
  19. package/es/server/index.d.ts +17 -0
  20. package/es/server/mockServer.d.ts +75 -0
  21. package/lib/client/index.d.ts +7 -0
  22. package/lib/client/index.js +59 -0
  23. package/lib/e2e/defineConfig.d.ts +2 -0
  24. package/lib/e2e/defineConfig.js +78 -0
  25. package/lib/e2e/e2eUtils.d.ts +298 -0
  26. package/lib/e2e/e2eUtils.js +633 -0
  27. package/lib/e2e/index.d.ts +3 -0
  28. package/lib/e2e/index.js +25 -0
  29. package/lib/e2e/templatesOfCollection.d.ts +41 -0
  30. package/lib/e2e/templatesOfCollection.js +720 -0
  31. package/lib/e2e/templatesOfPage.d.ts +573 -0
  32. package/lib/e2e/templatesOfPage.js +19345 -0
  33. package/lib/index.d.ts +1 -0
  34. package/lib/index.js +21 -0
  35. package/lib/scripts/test-db-creator.d.ts +1 -0
  36. package/lib/scripts/test-db-creator.js +163 -0
  37. package/lib/scripts/test-db-distributor.d.ts +1 -0
  38. package/lib/scripts/test-db-distributor.js +234 -0
  39. package/lib/server/index.d.ts +17 -0
  40. package/lib/server/index.js +105 -0
  41. package/lib/server/mockServer.d.ts +75 -0
  42. package/lib/server/mockServer.js +209 -0
  43. package/package.json +74 -0
  44. package/playwright/tests/auth.setup.ts +21 -0
  45. package/server.d.ts +1 -0
  46. package/server.js +1 -0
  47. package/setup/client.ts +69 -0
  48. package/setup/server.ts +5 -0
  49. package/vitest.d.ts +24 -0
  50. package/vitest.mjs +119 -0
package/es/index.mjs ADDED
@@ -0,0 +1,223 @@
1
+ import { describe } from "vitest";
2
+ import ws from "ws";
3
+ import { mockDatabase } from "@tachybase/database";
4
+ import { mockDatabase as mockDatabase2 } from "@tachybase/database";
5
+ import supertest from "supertest";
6
+ import { default as default2 } from "supertest";
7
+ import { Application, Gateway, AppSupervisor, PluginManager } from "@tachybase/server";
8
+ import jwt from "jsonwebtoken";
9
+ import qs from "qs";
10
+ class MockServer extends Application {
11
+ async loadAndInstall(options = {}) {
12
+ await this.load({ method: "install" });
13
+ if (options.afterLoad) {
14
+ await options.afterLoad(this);
15
+ }
16
+ await this.install({
17
+ ...options,
18
+ sync: {
19
+ force: false,
20
+ alter: {
21
+ drop: false
22
+ }
23
+ }
24
+ });
25
+ }
26
+ async cleanDb() {
27
+ await this.db.clean({ drop: true });
28
+ }
29
+ async quickstart(options = {}) {
30
+ const { clean } = options;
31
+ if (clean) {
32
+ await this.cleanDb();
33
+ }
34
+ await this.runCommand("start", "--quickstart");
35
+ }
36
+ async destroy(options = {}) {
37
+ await super.destroy(options);
38
+ Gateway.getInstance().destroy();
39
+ await AppSupervisor.getInstance().destroy();
40
+ }
41
+ agent() {
42
+ const agent = supertest.agent(this.callback());
43
+ const prefix = this.resourcer.options.prefix;
44
+ const proxy = new Proxy(agent, {
45
+ get(target, method, receiver) {
46
+ if (["login", "loginUsingId"].includes(method)) {
47
+ return (userOrId) => {
48
+ return proxy.auth(
49
+ jwt.sign(
50
+ {
51
+ userId: typeof userOrId === "number" ? userOrId : userOrId == null ? void 0 : userOrId.id
52
+ },
53
+ process.env.APP_KEY,
54
+ {
55
+ expiresIn: "1d"
56
+ }
57
+ ),
58
+ { type: "bearer" }
59
+ ).set("X-Authenticator", "basic");
60
+ };
61
+ }
62
+ if (method === "resource") {
63
+ return (name, resourceOf) => {
64
+ const keys = name.split(".");
65
+ const proxy2 = new Proxy(
66
+ {},
67
+ {
68
+ get(target2, method2, receiver2) {
69
+ return (params = {}) => {
70
+ let { filterByTk } = params;
71
+ const { values = {}, file, ...restParams } = params;
72
+ if (params.associatedIndex) {
73
+ resourceOf = params.associatedIndex;
74
+ }
75
+ if (params.resourceIndex) {
76
+ filterByTk = params.resourceIndex;
77
+ }
78
+ let url = prefix || "";
79
+ if (keys.length > 1) {
80
+ url += `/${keys[0]}/${resourceOf}/${keys[1]}`;
81
+ } else {
82
+ url += `/${name}`;
83
+ }
84
+ url += `:${method2}`;
85
+ if (filterByTk) {
86
+ url += `/${filterByTk}`;
87
+ }
88
+ const queryString = qs.stringify(restParams, { arrayFormat: "brackets" });
89
+ let request;
90
+ switch (method2) {
91
+ case "list":
92
+ case "get":
93
+ request = agent.get(`${url}?${queryString}`);
94
+ break;
95
+ default:
96
+ request = agent.post(`${url}?${queryString}`);
97
+ break;
98
+ }
99
+ return file ? request.attach("file", file).field(values) : request.send(values);
100
+ };
101
+ }
102
+ }
103
+ );
104
+ return proxy2;
105
+ };
106
+ }
107
+ return agent[method];
108
+ }
109
+ });
110
+ return proxy;
111
+ }
112
+ createDatabase(options) {
113
+ const oldDatabase = this.db;
114
+ const databaseOptions = oldDatabase ? oldDatabase.options : (options == null ? void 0 : options.database) || {};
115
+ const database = mockDatabase(databaseOptions);
116
+ database.setContext({ app: this });
117
+ return database;
118
+ }
119
+ }
120
+ function mockServer(options = {}) {
121
+ if (typeof TextEncoder === "undefined") {
122
+ global.TextEncoder = require("util").TextEncoder;
123
+ }
124
+ if (typeof TextDecoder === "undefined") {
125
+ global.TextDecoder = require("util").TextDecoder;
126
+ }
127
+ Gateway.getInstance().reset();
128
+ if (!PluginManager.findPackagePatched) {
129
+ PluginManager.getPackageJson = async () => {
130
+ return {
131
+ version: "0.0.0"
132
+ };
133
+ };
134
+ PluginManager.findPackagePatched = true;
135
+ }
136
+ const app = new MockServer({
137
+ acl: false,
138
+ ...options
139
+ });
140
+ return app;
141
+ }
142
+ async function startMockServer(options = {}) {
143
+ const app = mockServer(options);
144
+ await app.runCommand("start");
145
+ return app;
146
+ }
147
+ async function createMockServer(options = {}) {
148
+ const { version, beforeInstall, skipInstall, skipStart, ...others } = options;
149
+ const app = mockServer(others);
150
+ if (!skipInstall) {
151
+ if (beforeInstall) {
152
+ await beforeInstall(app);
153
+ }
154
+ await app.runCommandThrowError("install", "-f");
155
+ }
156
+ if (version) {
157
+ await app.version.update(version);
158
+ }
159
+ if (!skipStart) {
160
+ await app.runCommandThrowError("start");
161
+ }
162
+ return app;
163
+ }
164
+ const pgOnly = () => process.env.DB_DIALECT == "postgres" ? describe : describe.skip;
165
+ const isPg = () => process.env.DB_DIALECT == "postgres";
166
+ function randomStr() {
167
+ return Math.random().toString(36).substring(2);
168
+ }
169
+ const waitSecond = async (timeout = 1e3) => {
170
+ await new Promise((resolve) => setTimeout(resolve, timeout));
171
+ };
172
+ const startServerWithRandomPort = async (startServer) => {
173
+ return await new Promise((resolve) => {
174
+ startServer({
175
+ port: 0,
176
+ host: "localhost",
177
+ callback(server) {
178
+ const port = server.address().port;
179
+ resolve(port);
180
+ }
181
+ });
182
+ });
183
+ };
184
+ const createWsClient = async ({ serverPort, options = {} }) => {
185
+ console.log(`connect to ws://localhost:${serverPort}${process.env.WS_PATH}`, options);
186
+ const wsc = new ws(`ws://localhost:${serverPort}${process.env.WS_PATH}`, options);
187
+ const messages = [];
188
+ wsc.on("message", (data) => {
189
+ const message = data.toString();
190
+ messages.push(message);
191
+ });
192
+ await new Promise((resolve) => {
193
+ wsc.on("open", resolve);
194
+ });
195
+ return {
196
+ wsc,
197
+ messages,
198
+ async stop() {
199
+ const promise = new Promise((resolve) => {
200
+ wsc.on("close", resolve);
201
+ });
202
+ wsc.close();
203
+ await promise;
204
+ },
205
+ lastMessage() {
206
+ return JSON.parse(messages[messages.length - 1]);
207
+ }
208
+ };
209
+ };
210
+ export {
211
+ MockServer,
212
+ createMockServer,
213
+ createWsClient,
214
+ isPg,
215
+ mockDatabase2 as mockDatabase,
216
+ mockServer,
217
+ pgOnly,
218
+ randomStr,
219
+ startMockServer,
220
+ startServerWithRandomPort,
221
+ default2 as supertest,
222
+ waitSecond
223
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ export { mockDatabase } from '@tachybase/database';
2
+ export { default as supertest } from 'supertest';
3
+ export * from './mockServer';
4
+ export declare const pgOnly: () => any;
5
+ export declare const isPg: () => boolean;
6
+ export declare function randomStr(): string;
7
+ export declare const waitSecond: (timeout?: number) => Promise<void>;
8
+ export declare const startServerWithRandomPort: (startServer: any) => Promise<unknown>;
9
+ export declare const createWsClient: ({ serverPort, options }: {
10
+ serverPort: any;
11
+ options?: {};
12
+ }) => Promise<{
13
+ wsc: any;
14
+ messages: any[];
15
+ stop(): Promise<void>;
16
+ lastMessage(): any;
17
+ }>;
@@ -0,0 +1,75 @@
1
+ import { Application, ApplicationOptions } from '@tachybase/server';
2
+ import supertest, { SuperAgentTest } from 'supertest';
3
+ interface ActionParams {
4
+ filterByTk?: any;
5
+ fields?: string[];
6
+ filter?: any;
7
+ sort?: string[];
8
+ page?: number;
9
+ pageSize?: number;
10
+ values?: any;
11
+ /**
12
+ * @deprecated
13
+ */
14
+ resourceName?: string;
15
+ /**
16
+ * @deprecated
17
+ */
18
+ resourceIndex?: string;
19
+ /**
20
+ * @deprecated
21
+ */
22
+ associatedName?: string;
23
+ /**
24
+ * @deprecated
25
+ */
26
+ associatedIndex?: string;
27
+ [key: string]: any;
28
+ }
29
+ interface SortActionParams {
30
+ resourceName?: string;
31
+ resourceIndex?: any;
32
+ associatedName?: string;
33
+ associatedIndex?: any;
34
+ sourceId?: any;
35
+ targetId?: any;
36
+ sortField?: string;
37
+ method?: string;
38
+ target?: any;
39
+ sticky?: boolean;
40
+ [key: string]: any;
41
+ }
42
+ interface Resource {
43
+ get: (params?: ActionParams) => Promise<supertest.Response>;
44
+ list: (params?: ActionParams) => Promise<supertest.Response>;
45
+ create: (params?: ActionParams) => Promise<supertest.Response>;
46
+ update: (params?: ActionParams) => Promise<supertest.Response>;
47
+ destroy: (params?: ActionParams) => Promise<supertest.Response>;
48
+ sort: (params?: SortActionParams) => Promise<supertest.Response>;
49
+ [name: string]: (params?: ActionParams) => Promise<supertest.Response>;
50
+ }
51
+ interface ExtendedAgent extends SuperAgentTest {
52
+ login: (user: any) => ExtendedAgent;
53
+ loginUsingId: (userId: number) => ExtendedAgent;
54
+ resource: (name: string, resourceOf?: any) => Resource;
55
+ }
56
+ export declare class MockServer extends Application {
57
+ loadAndInstall(options?: any): Promise<void>;
58
+ cleanDb(): Promise<void>;
59
+ quickstart(options?: {
60
+ clean?: boolean;
61
+ }): Promise<void>;
62
+ destroy(options?: any): Promise<void>;
63
+ agent(): ExtendedAgent;
64
+ protected createDatabase(options: ApplicationOptions): import("@tachybase/database").MockDatabase;
65
+ }
66
+ export declare function mockServer(options?: ApplicationOptions): MockServer;
67
+ export declare function startMockServer(options?: ApplicationOptions): Promise<MockServer>;
68
+ type BeforeInstallFn = (app: any) => Promise<void>;
69
+ export declare function createMockServer(options?: ApplicationOptions & {
70
+ version?: string;
71
+ beforeInstall?: BeforeInstallFn;
72
+ skipInstall?: boolean;
73
+ skipStart?: boolean;
74
+ }): Promise<any>;
75
+ export default mockServer;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ export type { queries } from '@testing-library/dom';
3
+ declare function customRender(ui: React.ReactElement, options?: {}): import("@testing-library/react").RenderResult<typeof import("@testing-library/dom/types/queries"), HTMLElement, HTMLElement>;
4
+ export * from '@testing-library/react';
5
+ export { default as userEvent } from '@testing-library/user-event';
6
+ export { customRender as render };
7
+ export declare const sleep: (timeout?: number) => Promise<unknown>;
@@ -0,0 +1,59 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var client_exports = {};
31
+ __export(client_exports, {
32
+ render: () => customRender,
33
+ sleep: () => sleep,
34
+ userEvent: () => import_user_event.default
35
+ });
36
+ module.exports = __toCommonJS(client_exports);
37
+ var import_react2 = require("@testing-library/react");
38
+ __reExport(client_exports, require("@testing-library/react"), module.exports);
39
+ var import_user_event = __toESM(require("@testing-library/user-event"));
40
+ function customRender(ui, options = {}) {
41
+ return (0, import_react2.render)(ui, {
42
+ // wrap provider(s) here if needed
43
+ wrapper: /* @__PURE__ */ __name(({ children }) => children, "wrapper"),
44
+ ...options
45
+ });
46
+ }
47
+ __name(customRender, "customRender");
48
+ const sleep = /* @__PURE__ */ __name(async (timeout = 0) => {
49
+ return new Promise((resolve) => {
50
+ setTimeout(resolve, timeout);
51
+ });
52
+ }, "sleep");
53
+ // Annotate the CommonJS export names for ESM import in node:
54
+ 0 && (module.exports = {
55
+ render,
56
+ sleep,
57
+ userEvent,
58
+ ...require("@testing-library/react")
59
+ });
@@ -0,0 +1,2 @@
1
+ import { type PlaywrightTestConfig } from '@playwright/test';
2
+ export declare const defineConfig: (config?: PlaywrightTestConfig) => PlaywrightTestConfig<{}, {}>;
@@ -0,0 +1,78 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var defineConfig_exports = {};
20
+ __export(defineConfig_exports, {
21
+ defineConfig: () => defineConfig
22
+ });
23
+ module.exports = __toCommonJS(defineConfig_exports);
24
+ var import_test = require("@playwright/test");
25
+ const defineConfig = /* @__PURE__ */ __name((config) => {
26
+ return (0, import_test.defineConfig)({
27
+ timeout: 5 * 60 * 1e3,
28
+ expect: {
29
+ timeout: 10 * 1e3
30
+ },
31
+ // Look for test files in the "tests" directory, relative to this configuration file.
32
+ testDir: "packages",
33
+ // Match all test files in the e2e and __e2e__ directories.
34
+ testMatch: /(.*\/e2e\/|.*\/__e2e__\/).+\.test\.[tj]sx*$/,
35
+ // Run all tests in parallel.
36
+ fullyParallel: false,
37
+ // Fail the build on CI if you accidentally left test.only in the source code.
38
+ forbidOnly: !!process.env.CI,
39
+ retries: 2,
40
+ // Opt out of parallel tests on CI.
41
+ // workers: process.env.CI ? 1 : undefined,
42
+ workers: 1,
43
+ maxFailures: 0,
44
+ // Reporter to use
45
+ reporter: process.env.PLAYWRIGHT_SKIP_REPORTER ? void 0 : [["html", { outputFolder: "./storage/playwright/tests-report" }]],
46
+ outputDir: "./storage/playwright/test-results",
47
+ use: {
48
+ // Base URL to use in actions like `await page.goto('/')`.
49
+ baseURL: process.env.APP_BASE_URL || `http://localhost:${process.env.APP_PORT || 2e4}`,
50
+ // Collect trace when retrying the failed test.
51
+ trace: "on-first-retry"
52
+ },
53
+ // Configure projects for major browsers.
54
+ projects: [
55
+ {
56
+ name: "authSetup",
57
+ testDir: "./storage/playwright/tests",
58
+ testMatch: "auth.setup.ts"
59
+ },
60
+ {
61
+ name: "chromium",
62
+ use: {
63
+ ...import_test.devices["Desktop Chrome"],
64
+ storageState: process.env.PLAYWRIGHT_AUTH_FILE,
65
+ contextOptions: {
66
+ // chromium-specific permissions
67
+ permissions: ["clipboard-read", "clipboard-write"]
68
+ }
69
+ },
70
+ dependencies: ["authSetup"]
71
+ }
72
+ ]
73
+ });
74
+ }, "defineConfig");
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ defineConfig
78
+ });