@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.
- package/.turbo/turbo-build.log +24 -0
- package/LICENSE +201 -0
- package/client.d.ts +1 -0
- package/client.js +1 -0
- package/e2e.d.ts +1 -0
- package/e2e.js +1 -0
- package/es/client/index.d.ts +7 -0
- package/es/client/index.mjs +20 -0
- package/es/e2e/defineConfig.d.ts +2 -0
- package/es/e2e/e2eUtils.d.ts +298 -0
- package/es/e2e/index.d.ts +3 -0
- package/es/e2e/index.mjs +20547 -0
- package/es/e2e/templatesOfCollection.d.ts +41 -0
- package/es/e2e/templatesOfPage.d.ts +573 -0
- package/es/index.d.ts +1 -0
- package/es/index.mjs +223 -0
- package/es/scripts/test-db-creator.d.ts +1 -0
- package/es/scripts/test-db-distributor.d.ts +1 -0
- package/es/server/index.d.ts +17 -0
- package/es/server/mockServer.d.ts +75 -0
- package/lib/client/index.d.ts +7 -0
- package/lib/client/index.js +59 -0
- package/lib/e2e/defineConfig.d.ts +2 -0
- package/lib/e2e/defineConfig.js +78 -0
- package/lib/e2e/e2eUtils.d.ts +298 -0
- package/lib/e2e/e2eUtils.js +633 -0
- package/lib/e2e/index.d.ts +3 -0
- package/lib/e2e/index.js +25 -0
- package/lib/e2e/templatesOfCollection.d.ts +41 -0
- package/lib/e2e/templatesOfCollection.js +720 -0
- package/lib/e2e/templatesOfPage.d.ts +573 -0
- package/lib/e2e/templatesOfPage.js +19345 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +21 -0
- package/lib/scripts/test-db-creator.d.ts +1 -0
- package/lib/scripts/test-db-creator.js +163 -0
- package/lib/scripts/test-db-distributor.d.ts +1 -0
- package/lib/scripts/test-db-distributor.js +234 -0
- package/lib/server/index.d.ts +17 -0
- package/lib/server/index.js +105 -0
- package/lib/server/mockServer.d.ts +75 -0
- package/lib/server/mockServer.js +209 -0
- package/package.json +74 -0
- package/playwright/tests/auth.setup.ts +21 -0
- package/server.d.ts +1 -0
- package/server.js +1 -0
- package/setup/client.ts +69 -0
- package/setup/server.ts +5 -0
- package/vitest.d.ts +24 -0
- package/vitest.mjs +119 -0
|
@@ -0,0 +1,633 @@
|
|
|
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 e2eUtils_exports = {};
|
|
31
|
+
__export(e2eUtils_exports, {
|
|
32
|
+
NocoPage: () => NocoPage,
|
|
33
|
+
createBlockInPage: () => createBlockInPage,
|
|
34
|
+
defineConfig: () => import_defineConfig.defineConfig,
|
|
35
|
+
expectInitializerMenu: () => expectInitializerMenu,
|
|
36
|
+
expectSettingsMenu: () => expectSettingsMenu,
|
|
37
|
+
omitSomeFields: () => omitSomeFields,
|
|
38
|
+
test: () => test
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(e2eUtils_exports);
|
|
41
|
+
var import_faker = require("@faker-js/faker");
|
|
42
|
+
var import_shared = require("@formily/shared");
|
|
43
|
+
var import_test = require("@playwright/test");
|
|
44
|
+
var import_lodash = __toESM(require("lodash"));
|
|
45
|
+
var import_defineConfig = require("./defineConfig");
|
|
46
|
+
__reExport(e2eUtils_exports, require("@playwright/test"), module.exports);
|
|
47
|
+
const PORT = process.env.APP_PORT || 2e4;
|
|
48
|
+
const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
|
|
49
|
+
const _NocoPage = class _NocoPage {
|
|
50
|
+
constructor(options, page) {
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.page = page;
|
|
53
|
+
this._waitForInit = this.init();
|
|
54
|
+
}
|
|
55
|
+
url;
|
|
56
|
+
uid;
|
|
57
|
+
collectionsName;
|
|
58
|
+
_waitForInit;
|
|
59
|
+
async init() {
|
|
60
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
61
|
+
if ((_b = (_a = this.options) == null ? void 0 : _a.collections) == null ? void 0 : _b.length) {
|
|
62
|
+
const collections = omitSomeFields(this.options.collections);
|
|
63
|
+
this.collectionsName = collections.map((item) => item.name);
|
|
64
|
+
await createCollections(collections);
|
|
65
|
+
}
|
|
66
|
+
this.uid = await createPage({
|
|
67
|
+
type: (_c = this.options) == null ? void 0 : _c.type,
|
|
68
|
+
name: (_d = this.options) == null ? void 0 : _d.name,
|
|
69
|
+
pageSchema: (_e = this.options) == null ? void 0 : _e.pageSchema,
|
|
70
|
+
url: (_f = this.options) == null ? void 0 : _f.url
|
|
71
|
+
});
|
|
72
|
+
this.url = `${((_g = this.options) == null ? void 0 : _g.basePath) || "/admin/"}${this.uid}`;
|
|
73
|
+
}
|
|
74
|
+
async goto() {
|
|
75
|
+
var _a;
|
|
76
|
+
await this._waitForInit;
|
|
77
|
+
await ((_a = this.page) == null ? void 0 : _a.goto(this.url));
|
|
78
|
+
}
|
|
79
|
+
async getUrl() {
|
|
80
|
+
await this._waitForInit;
|
|
81
|
+
return this.url;
|
|
82
|
+
}
|
|
83
|
+
async getUid() {
|
|
84
|
+
await this._waitForInit;
|
|
85
|
+
return this.uid;
|
|
86
|
+
}
|
|
87
|
+
async waitForInit() {
|
|
88
|
+
await this._waitForInit;
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
async destroy() {
|
|
92
|
+
var _a;
|
|
93
|
+
if (this.uid) {
|
|
94
|
+
await deletePage(this.uid);
|
|
95
|
+
this.uid = void 0;
|
|
96
|
+
}
|
|
97
|
+
if ((_a = this.collectionsName) == null ? void 0 : _a.length) {
|
|
98
|
+
await deleteCollections(this.collectionsName);
|
|
99
|
+
this.collectionsName = void 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
__name(_NocoPage, "NocoPage");
|
|
104
|
+
let NocoPage = _NocoPage;
|
|
105
|
+
const _test = import_test.test.extend({
|
|
106
|
+
mockPage: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
107
|
+
const nocoPages = [];
|
|
108
|
+
const mockPage = /* @__PURE__ */ __name((config) => {
|
|
109
|
+
const nocoPage = new NocoPage(config, page);
|
|
110
|
+
nocoPages.push(nocoPage);
|
|
111
|
+
return nocoPage;
|
|
112
|
+
}, "mockPage");
|
|
113
|
+
await use(mockPage);
|
|
114
|
+
for (const nocoPage of nocoPages) {
|
|
115
|
+
await nocoPage.destroy();
|
|
116
|
+
await setDefaultRole("root");
|
|
117
|
+
}
|
|
118
|
+
}, "mockPage"),
|
|
119
|
+
mockManualDestroyPage: /* @__PURE__ */ __name(async ({ browser }, use) => {
|
|
120
|
+
const mockManualDestroyPage = /* @__PURE__ */ __name((config) => {
|
|
121
|
+
const nocoPage = new NocoPage(config);
|
|
122
|
+
return nocoPage;
|
|
123
|
+
}, "mockManualDestroyPage");
|
|
124
|
+
await use(mockManualDestroyPage);
|
|
125
|
+
}, "mockManualDestroyPage"),
|
|
126
|
+
createCollections: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
127
|
+
let collectionsName = [];
|
|
128
|
+
const _createCollections = /* @__PURE__ */ __name(async (collectionSettings) => {
|
|
129
|
+
collectionSettings = omitSomeFields(
|
|
130
|
+
Array.isArray(collectionSettings) ? collectionSettings : [collectionSettings]
|
|
131
|
+
);
|
|
132
|
+
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
|
133
|
+
await createCollections(collectionSettings);
|
|
134
|
+
}, "_createCollections");
|
|
135
|
+
await use(_createCollections);
|
|
136
|
+
if (collectionsName.length) {
|
|
137
|
+
await deleteCollections(import_lodash.default.uniq(collectionsName));
|
|
138
|
+
}
|
|
139
|
+
}, "createCollections"),
|
|
140
|
+
mockCollections: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
141
|
+
let collectionsName = [];
|
|
142
|
+
const destroy = /* @__PURE__ */ __name(async () => {
|
|
143
|
+
if (collectionsName.length) {
|
|
144
|
+
await deleteCollections(import_lodash.default.uniq(collectionsName));
|
|
145
|
+
}
|
|
146
|
+
}, "destroy");
|
|
147
|
+
const mockCollections = /* @__PURE__ */ __name(async (collectionSettings) => {
|
|
148
|
+
collectionSettings = omitSomeFields(collectionSettings);
|
|
149
|
+
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
|
150
|
+
return createCollections(collectionSettings);
|
|
151
|
+
}, "mockCollections");
|
|
152
|
+
await use(mockCollections);
|
|
153
|
+
await destroy();
|
|
154
|
+
}, "mockCollections"),
|
|
155
|
+
mockCollection: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
156
|
+
let collectionsName = [];
|
|
157
|
+
const destroy = /* @__PURE__ */ __name(async () => {
|
|
158
|
+
if (collectionsName.length) {
|
|
159
|
+
await deleteCollections(import_lodash.default.uniq(collectionsName));
|
|
160
|
+
}
|
|
161
|
+
}, "destroy");
|
|
162
|
+
const mockCollection = /* @__PURE__ */ __name(async (collectionSetting, options) => {
|
|
163
|
+
const collectionSettings = omitSomeFields([collectionSetting]);
|
|
164
|
+
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
|
165
|
+
return createCollections(collectionSettings);
|
|
166
|
+
}, "mockCollection");
|
|
167
|
+
await use(mockCollection);
|
|
168
|
+
await destroy();
|
|
169
|
+
}, "mockCollection"),
|
|
170
|
+
mockRecords: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
171
|
+
const mockRecords = /* @__PURE__ */ __name(async (collectionName, count = 3, data) => {
|
|
172
|
+
if (import_lodash.default.isArray(count)) {
|
|
173
|
+
data = count;
|
|
174
|
+
count = data.length;
|
|
175
|
+
}
|
|
176
|
+
return createRandomData(collectionName, count, data);
|
|
177
|
+
}, "mockRecords");
|
|
178
|
+
await use(mockRecords);
|
|
179
|
+
const deletePromises = [
|
|
180
|
+
deleteRecords("users", { id: { $ne: 1 } }),
|
|
181
|
+
deleteRecords("roles", { name: { $ne: ["root", "admin", "member"] } })
|
|
182
|
+
];
|
|
183
|
+
await Promise.all(deletePromises);
|
|
184
|
+
}, "mockRecords"),
|
|
185
|
+
mockRecord: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
186
|
+
const mockRecord = /* @__PURE__ */ __name(async (collectionName, data) => {
|
|
187
|
+
const result = await createRandomData(collectionName, 1, data);
|
|
188
|
+
return result[0];
|
|
189
|
+
}, "mockRecord");
|
|
190
|
+
await use(mockRecord);
|
|
191
|
+
const deletePromises = [
|
|
192
|
+
deleteRecords("users", { id: { $ne: 1 } }),
|
|
193
|
+
deleteRecords("roles", { name: { $ne: ["root", "admin", "member"] } })
|
|
194
|
+
];
|
|
195
|
+
await Promise.all(deletePromises);
|
|
196
|
+
}, "mockRecord"),
|
|
197
|
+
deletePage: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
198
|
+
const deletePage2 = /* @__PURE__ */ __name(async (pageName) => {
|
|
199
|
+
await page.getByText(pageName, { exact: true }).hover();
|
|
200
|
+
await page.getByRole("button", { name: "designer-schema-settings-" }).hover();
|
|
201
|
+
await page.getByRole("menuitem", { name: "Delete", exact: true }).click();
|
|
202
|
+
await page.getByRole("button", { name: "OK", exact: true }).click();
|
|
203
|
+
}, "deletePage");
|
|
204
|
+
await use(deletePage2);
|
|
205
|
+
const deletePromises = [
|
|
206
|
+
deleteRecords("users", { id: { $ne: 1 } }),
|
|
207
|
+
deleteRecords("roles", { name: { $ne: ["root", "admin", "member"] } })
|
|
208
|
+
];
|
|
209
|
+
await Promise.all(deletePromises);
|
|
210
|
+
}, "deletePage"),
|
|
211
|
+
mockRole: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
212
|
+
const mockRole = /* @__PURE__ */ __name(async (roleSetting) => {
|
|
213
|
+
return createRole(roleSetting);
|
|
214
|
+
}, "mockRole");
|
|
215
|
+
await use(mockRole);
|
|
216
|
+
}, "mockRole"),
|
|
217
|
+
updateRole: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
218
|
+
const updateRole2 = /* @__PURE__ */ __name(async (roleSetting) => {
|
|
219
|
+
return updateRole2(roleSetting);
|
|
220
|
+
}, "updateRole");
|
|
221
|
+
await use(updateRole2);
|
|
222
|
+
}, "updateRole"),
|
|
223
|
+
mockExternalDataSource: /* @__PURE__ */ __name(async ({ browser }, use) => {
|
|
224
|
+
const mockExternalDataSource = /* @__PURE__ */ __name(async (DataSourceSetting) => {
|
|
225
|
+
return createExternalDataSource(DataSourceSetting);
|
|
226
|
+
}, "mockExternalDataSource");
|
|
227
|
+
await use(mockExternalDataSource);
|
|
228
|
+
}, "mockExternalDataSource"),
|
|
229
|
+
destoryExternalDataSource: /* @__PURE__ */ __name(async ({ browser }, use) => {
|
|
230
|
+
const destoryDataSource = /* @__PURE__ */ __name(async (key) => {
|
|
231
|
+
return destoryExternalDataSource(key);
|
|
232
|
+
}, "destoryDataSource");
|
|
233
|
+
await use(destoryDataSource);
|
|
234
|
+
}, "destoryExternalDataSource"),
|
|
235
|
+
clearBlockTemplates: /* @__PURE__ */ __name(async ({ page }, use) => {
|
|
236
|
+
const clearBlockTemplates = /* @__PURE__ */ __name(async () => {
|
|
237
|
+
const api = await import_test.request.newContext({
|
|
238
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
239
|
+
});
|
|
240
|
+
const state = await api.storageState();
|
|
241
|
+
const headers = getHeaders(state);
|
|
242
|
+
const filter = {
|
|
243
|
+
key: { $exists: true }
|
|
244
|
+
};
|
|
245
|
+
const result = await api.post(`/api/uiSchemaTemplates:destroy?filter=${JSON.stringify(filter)}`, {
|
|
246
|
+
headers
|
|
247
|
+
});
|
|
248
|
+
if (!result.ok()) {
|
|
249
|
+
throw new Error(await result.text());
|
|
250
|
+
}
|
|
251
|
+
}, "clearBlockTemplates");
|
|
252
|
+
try {
|
|
253
|
+
await use(clearBlockTemplates);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
await clearBlockTemplates();
|
|
256
|
+
}
|
|
257
|
+
}, "clearBlockTemplates")
|
|
258
|
+
});
|
|
259
|
+
const test = Object.assign(_test, {
|
|
260
|
+
/** 只运行在 postgres 数据库中 */
|
|
261
|
+
pgOnly: process.env.DB_DIALECT == "postgres" ? _test : _test.skip
|
|
262
|
+
});
|
|
263
|
+
const getStorageItem = /* @__PURE__ */ __name((key, storageState) => {
|
|
264
|
+
var _a, _b;
|
|
265
|
+
return (_b = (_a = storageState.origins.find((item) => item.origin === APP_BASE_URL)) == null ? void 0 : _a.localStorage.find((item) => item.name === key)) == null ? void 0 : _b.value;
|
|
266
|
+
}, "getStorageItem");
|
|
267
|
+
const updateUidOfPageSchema = /* @__PURE__ */ __name((uiSchema) => {
|
|
268
|
+
if (!uiSchema) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (uiSchema["x-uid"]) {
|
|
272
|
+
uiSchema["x-uid"] = (0, import_shared.uid)();
|
|
273
|
+
}
|
|
274
|
+
if (uiSchema.properties) {
|
|
275
|
+
Object.keys(uiSchema.properties).forEach((key) => {
|
|
276
|
+
updateUidOfPageSchema(uiSchema.properties[key]);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return uiSchema;
|
|
280
|
+
}, "updateUidOfPageSchema");
|
|
281
|
+
const createPage = /* @__PURE__ */ __name(async (options) => {
|
|
282
|
+
const { type = "page", url, name, pageSchema } = options || {};
|
|
283
|
+
const api = await import_test.request.newContext({
|
|
284
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
285
|
+
});
|
|
286
|
+
const typeToSchema = {
|
|
287
|
+
group: {
|
|
288
|
+
"x-component": "Menu.SubMenu",
|
|
289
|
+
"x-component-props": {}
|
|
290
|
+
},
|
|
291
|
+
page: {
|
|
292
|
+
"x-component": "Menu.Item",
|
|
293
|
+
"x-component-props": {}
|
|
294
|
+
},
|
|
295
|
+
link: {
|
|
296
|
+
"x-component": "Menu.URL",
|
|
297
|
+
"x-component-props": {
|
|
298
|
+
href: url
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
const state = await api.storageState();
|
|
303
|
+
const headers = getHeaders(state);
|
|
304
|
+
const pageUid = (0, import_shared.uid)();
|
|
305
|
+
const gridName = (0, import_shared.uid)();
|
|
306
|
+
const result = await api.post(`/api/uiSchemas:insertAdjacent/default-admin-menu?position=beforeEnd`, {
|
|
307
|
+
headers,
|
|
308
|
+
data: {
|
|
309
|
+
schema: {
|
|
310
|
+
_isJSONSchemaObject: true,
|
|
311
|
+
version: "2.0",
|
|
312
|
+
type: "void",
|
|
313
|
+
title: name || pageUid,
|
|
314
|
+
...typeToSchema[type],
|
|
315
|
+
"x-decorator": "ACLMenuItemProvider",
|
|
316
|
+
"x-server-hooks": [
|
|
317
|
+
{ type: "onSelfCreate", method: "bindMenuToRole" },
|
|
318
|
+
{ type: "onSelfSave", method: "extractTextToLocale" }
|
|
319
|
+
],
|
|
320
|
+
properties: {
|
|
321
|
+
page: updateUidOfPageSchema(pageSchema) || {
|
|
322
|
+
_isJSONSchemaObject: true,
|
|
323
|
+
version: "2.0",
|
|
324
|
+
type: "void",
|
|
325
|
+
"x-component": "Page",
|
|
326
|
+
"x-async": true,
|
|
327
|
+
properties: {
|
|
328
|
+
[gridName]: {
|
|
329
|
+
_isJSONSchemaObject: true,
|
|
330
|
+
version: "2.0",
|
|
331
|
+
type: "void",
|
|
332
|
+
"x-component": "Grid",
|
|
333
|
+
"x-initializer": "page:addBlock",
|
|
334
|
+
"x-uid": (0, import_shared.uid)(),
|
|
335
|
+
name: gridName
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
"x-uid": (0, import_shared.uid)(),
|
|
339
|
+
name: "page"
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
name: (0, import_shared.uid)(),
|
|
343
|
+
"x-uid": pageUid
|
|
344
|
+
},
|
|
345
|
+
wrap: null
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
if (!result.ok()) {
|
|
349
|
+
throw new Error(await result.text());
|
|
350
|
+
}
|
|
351
|
+
return pageUid;
|
|
352
|
+
}, "createPage");
|
|
353
|
+
const deletePage = /* @__PURE__ */ __name(async (pageUid) => {
|
|
354
|
+
const api = await import_test.request.newContext({
|
|
355
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
356
|
+
});
|
|
357
|
+
const state = await api.storageState();
|
|
358
|
+
const headers = getHeaders(state);
|
|
359
|
+
const result = await api.post(`/api/uiSchemas:remove/${pageUid}`, {
|
|
360
|
+
headers
|
|
361
|
+
});
|
|
362
|
+
if (!result.ok()) {
|
|
363
|
+
throw new Error(await result.text());
|
|
364
|
+
}
|
|
365
|
+
}, "deletePage");
|
|
366
|
+
const deleteCollections = /* @__PURE__ */ __name(async (collectionNames) => {
|
|
367
|
+
const api = await import_test.request.newContext({
|
|
368
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
369
|
+
});
|
|
370
|
+
const state = await api.storageState();
|
|
371
|
+
const headers = getHeaders(state);
|
|
372
|
+
const params = collectionNames.map((name) => `filterByTk[]=${name}`).join("&");
|
|
373
|
+
const result = await api.post(`/api/collections:destroy?${params}`, {
|
|
374
|
+
headers,
|
|
375
|
+
params: {
|
|
376
|
+
cascade: true
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
if (!result.ok()) {
|
|
380
|
+
throw new Error(await result.text());
|
|
381
|
+
}
|
|
382
|
+
}, "deleteCollections");
|
|
383
|
+
const deleteRecords = /* @__PURE__ */ __name(async (collectionName, filter) => {
|
|
384
|
+
const api = await import_test.request.newContext({
|
|
385
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
386
|
+
});
|
|
387
|
+
const state = await api.storageState();
|
|
388
|
+
const headers = getHeaders(state);
|
|
389
|
+
const result = await api.post(`/api/${collectionName}:destroy?filter=${JSON.stringify(filter)}`, {
|
|
390
|
+
headers
|
|
391
|
+
});
|
|
392
|
+
if (!result.ok()) {
|
|
393
|
+
throw new Error(await result.text());
|
|
394
|
+
}
|
|
395
|
+
}, "deleteRecords");
|
|
396
|
+
const omitSomeFields = /* @__PURE__ */ __name((collectionSettings) => {
|
|
397
|
+
return collectionSettings.map((collection) => {
|
|
398
|
+
var _a;
|
|
399
|
+
return {
|
|
400
|
+
...import_lodash.default.omit(collection, ["key"]),
|
|
401
|
+
fields: (_a = collection.fields) == null ? void 0 : _a.map((field) => import_lodash.default.omit(field, ["key", "collectionName"]))
|
|
402
|
+
};
|
|
403
|
+
});
|
|
404
|
+
}, "omitSomeFields");
|
|
405
|
+
const createCollections = /* @__PURE__ */ __name(async (collectionSettings) => {
|
|
406
|
+
const api = await import_test.request.newContext({
|
|
407
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
408
|
+
});
|
|
409
|
+
const state = await api.storageState();
|
|
410
|
+
const headers = getHeaders(state);
|
|
411
|
+
collectionSettings = Array.isArray(collectionSettings) ? collectionSettings : [collectionSettings];
|
|
412
|
+
const result = await api.post(`/api/collections:mock`, {
|
|
413
|
+
headers,
|
|
414
|
+
data: collectionSettings
|
|
415
|
+
});
|
|
416
|
+
if (!result.ok()) {
|
|
417
|
+
throw new Error(await result.text());
|
|
418
|
+
}
|
|
419
|
+
return (await result.json()).data;
|
|
420
|
+
}, "createCollections");
|
|
421
|
+
const createRole = /* @__PURE__ */ __name(async (roleSetting) => {
|
|
422
|
+
const api = await import_test.request.newContext({
|
|
423
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
424
|
+
});
|
|
425
|
+
const state = await api.storageState();
|
|
426
|
+
const headers = getHeaders(state);
|
|
427
|
+
const name = roleSetting.name || (0, import_shared.uid)();
|
|
428
|
+
const result = await api.post(`/api/users/1/roles:create`, {
|
|
429
|
+
headers,
|
|
430
|
+
data: { ...roleSetting, name, title: name }
|
|
431
|
+
});
|
|
432
|
+
if (!result.ok()) {
|
|
433
|
+
throw new Error(await result.text());
|
|
434
|
+
}
|
|
435
|
+
const roleData = (await result.json()).data;
|
|
436
|
+
await setDefaultRole(name);
|
|
437
|
+
return roleData;
|
|
438
|
+
}, "createRole");
|
|
439
|
+
const updateRole = /* @__PURE__ */ __name(async (roleSetting) => {
|
|
440
|
+
const api = await import_test.request.newContext({
|
|
441
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
442
|
+
});
|
|
443
|
+
const state = await api.storageState();
|
|
444
|
+
const headers = getHeaders(state);
|
|
445
|
+
const name = roleSetting.name;
|
|
446
|
+
const dataSourceKey = roleSetting.dataSourceKey;
|
|
447
|
+
const url = !dataSourceKey ? `/api/roles:update?filterByTk=${name}` : `/api/dataSources/${dataSourceKey}/roles:update?filterByTk=${name}`;
|
|
448
|
+
const result = await api.post(url, {
|
|
449
|
+
headers,
|
|
450
|
+
data: { ...roleSetting }
|
|
451
|
+
});
|
|
452
|
+
if (!result.ok()) {
|
|
453
|
+
throw new Error(await result.text());
|
|
454
|
+
}
|
|
455
|
+
const roleData = (await result.json()).data;
|
|
456
|
+
return roleData;
|
|
457
|
+
}, "updateRole");
|
|
458
|
+
const setDefaultRole = /* @__PURE__ */ __name(async (name) => {
|
|
459
|
+
const api = await import_test.request.newContext({
|
|
460
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
461
|
+
});
|
|
462
|
+
const state = await api.storageState();
|
|
463
|
+
const headers = getHeaders(state);
|
|
464
|
+
await api.post(`/api/users:setDefaultRole`, {
|
|
465
|
+
headers,
|
|
466
|
+
data: { roleName: name }
|
|
467
|
+
});
|
|
468
|
+
}, "setDefaultRole");
|
|
469
|
+
const createExternalDataSource = /* @__PURE__ */ __name(async (dataSourceSetting) => {
|
|
470
|
+
const api = await import_test.request.newContext({
|
|
471
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
472
|
+
});
|
|
473
|
+
const state = await api.storageState();
|
|
474
|
+
const headers = getHeaders(state);
|
|
475
|
+
const result = await api.post(`/api/dataSources:create`, {
|
|
476
|
+
headers,
|
|
477
|
+
data: { ...dataSourceSetting }
|
|
478
|
+
});
|
|
479
|
+
if (!result.ok()) {
|
|
480
|
+
throw new Error(await result.text());
|
|
481
|
+
}
|
|
482
|
+
const dataSourceData = (await result.json()).data;
|
|
483
|
+
return dataSourceData;
|
|
484
|
+
}, "createExternalDataSource");
|
|
485
|
+
const destoryExternalDataSource = /* @__PURE__ */ __name(async (key) => {
|
|
486
|
+
const api = await import_test.request.newContext({
|
|
487
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
488
|
+
});
|
|
489
|
+
const state = await api.storageState();
|
|
490
|
+
const headers = getHeaders(state);
|
|
491
|
+
const result = await api.post(`/api/dataSources:destroy?filterByTk=${key}`, {
|
|
492
|
+
headers
|
|
493
|
+
});
|
|
494
|
+
if (!result.ok()) {
|
|
495
|
+
throw new Error(await result.text());
|
|
496
|
+
}
|
|
497
|
+
const dataSourceData = (await result.json()).data;
|
|
498
|
+
return dataSourceData;
|
|
499
|
+
}, "destoryExternalDataSource");
|
|
500
|
+
const generateFakerData = /* @__PURE__ */ __name((collectionSetting) => {
|
|
501
|
+
var _a;
|
|
502
|
+
const excludeField = ["id", "createdAt", "updatedAt", "createdBy", "updatedBy"];
|
|
503
|
+
const basicInterfaceToData = {
|
|
504
|
+
input: /* @__PURE__ */ __name(() => import_faker.faker.lorem.words(), "input"),
|
|
505
|
+
textarea: /* @__PURE__ */ __name(() => import_faker.faker.lorem.paragraph(), "textarea"),
|
|
506
|
+
richText: /* @__PURE__ */ __name(() => import_faker.faker.lorem.paragraph(), "richText"),
|
|
507
|
+
phone: /* @__PURE__ */ __name(() => import_faker.faker.phone.number(), "phone"),
|
|
508
|
+
email: /* @__PURE__ */ __name(() => import_faker.faker.internet.email(), "email"),
|
|
509
|
+
url: /* @__PURE__ */ __name(() => import_faker.faker.internet.url(), "url"),
|
|
510
|
+
integer: /* @__PURE__ */ __name(() => import_faker.faker.number.int(), "integer"),
|
|
511
|
+
number: /* @__PURE__ */ __name(() => import_faker.faker.number.int(), "number"),
|
|
512
|
+
percent: /* @__PURE__ */ __name(() => import_faker.faker.number.float(), "percent"),
|
|
513
|
+
password: /* @__PURE__ */ __name(() => import_faker.faker.internet.password(), "password"),
|
|
514
|
+
color: /* @__PURE__ */ __name(() => import_faker.faker.internet.color(), "color"),
|
|
515
|
+
icon: /* @__PURE__ */ __name(() => "checkcircleoutlined", "icon"),
|
|
516
|
+
datetime: /* @__PURE__ */ __name(() => import_faker.faker.date.anytime({ refDate: "2023-09-21T00:00:00.000Z" }), "datetime"),
|
|
517
|
+
time: /* @__PURE__ */ __name(() => "00:00:00", "time")
|
|
518
|
+
};
|
|
519
|
+
const result = {};
|
|
520
|
+
(_a = collectionSetting.fields) == null ? void 0 : _a.forEach((field) => {
|
|
521
|
+
if (field.name && excludeField.includes(field.name)) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
if (basicInterfaceToData[field.interface] && field.name) {
|
|
525
|
+
result[field.name] = basicInterfaceToData[field.interface]();
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
return result;
|
|
529
|
+
}, "generateFakerData");
|
|
530
|
+
const createRandomData = /* @__PURE__ */ __name(async (collectionName, count = 10, data) => {
|
|
531
|
+
const api = await import_test.request.newContext({
|
|
532
|
+
storageState: process.env.PLAYWRIGHT_AUTH_FILE
|
|
533
|
+
});
|
|
534
|
+
const state = await api.storageState();
|
|
535
|
+
const headers = getHeaders(state);
|
|
536
|
+
const result = await api.post(`/api/${collectionName}:mock?count=${count}`, {
|
|
537
|
+
headers,
|
|
538
|
+
data
|
|
539
|
+
});
|
|
540
|
+
if (!result.ok()) {
|
|
541
|
+
throw new Error(await result.text());
|
|
542
|
+
}
|
|
543
|
+
return (await result.json()).data;
|
|
544
|
+
}, "createRandomData");
|
|
545
|
+
function getHeaders(storageState) {
|
|
546
|
+
var _a;
|
|
547
|
+
const headers = {};
|
|
548
|
+
const token = getStorageItem("TACHYBASE_TOKEN", storageState);
|
|
549
|
+
const auth = getStorageItem("TACHYBASE_AUTH", storageState);
|
|
550
|
+
const subAppName = (_a = new URL(APP_BASE_URL).pathname.match(/^\/apps\/([^/]*)\/*/)) == null ? void 0 : _a[1];
|
|
551
|
+
const hostName = new URL(APP_BASE_URL).host;
|
|
552
|
+
const locale = getStorageItem("TACHYBASE_LOCALE", storageState);
|
|
553
|
+
const timezone = "+08:00";
|
|
554
|
+
const withAclMeta = "true";
|
|
555
|
+
const role = getStorageItem("TACHYBASE_ROLE", storageState);
|
|
556
|
+
if (token) {
|
|
557
|
+
headers.Authorization = `Bearer ${token}`;
|
|
558
|
+
}
|
|
559
|
+
if (auth) {
|
|
560
|
+
headers["X-Authenticator"] = auth;
|
|
561
|
+
}
|
|
562
|
+
if (subAppName) {
|
|
563
|
+
headers["X-App"] = subAppName;
|
|
564
|
+
}
|
|
565
|
+
if (hostName) {
|
|
566
|
+
headers["X-Hostname"] = hostName;
|
|
567
|
+
}
|
|
568
|
+
if (locale) {
|
|
569
|
+
headers["X-Locale"] = locale;
|
|
570
|
+
}
|
|
571
|
+
if (timezone) {
|
|
572
|
+
headers["X-Timezone"] = timezone;
|
|
573
|
+
}
|
|
574
|
+
if (withAclMeta) {
|
|
575
|
+
headers["X-With-Acl-Meta"] = withAclMeta;
|
|
576
|
+
}
|
|
577
|
+
if (role) {
|
|
578
|
+
headers["X-Role"] = role;
|
|
579
|
+
}
|
|
580
|
+
return headers;
|
|
581
|
+
}
|
|
582
|
+
__name(getHeaders, "getHeaders");
|
|
583
|
+
async function expectSettingsMenu({
|
|
584
|
+
showMenu,
|
|
585
|
+
supportedOptions,
|
|
586
|
+
page,
|
|
587
|
+
unsupportedOptions
|
|
588
|
+
}) {
|
|
589
|
+
await showMenu();
|
|
590
|
+
for (const option of supportedOptions) {
|
|
591
|
+
await (0, import_test.expect)(page.getByRole("menuitem", { name: option })).toBeVisible();
|
|
592
|
+
}
|
|
593
|
+
if (unsupportedOptions) {
|
|
594
|
+
for (const option of unsupportedOptions) {
|
|
595
|
+
await (0, import_test.expect)(page.getByRole("menuitem", { name: option })).not.toBeVisible();
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
__name(expectSettingsMenu, "expectSettingsMenu");
|
|
600
|
+
async function expectInitializerMenu({ showMenu, supportedOptions, page }) {
|
|
601
|
+
await showMenu();
|
|
602
|
+
for (const option of supportedOptions) {
|
|
603
|
+
await (0, import_test.expect)(page.getByRole("menuitem", { name: option }).first()).toBeVisible();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
__name(expectInitializerMenu, "expectInitializerMenu");
|
|
607
|
+
const createBlockInPage = /* @__PURE__ */ __name(async (page, name) => {
|
|
608
|
+
await page.getByLabel("schema-initializer-Grid-page:addBlock").hover();
|
|
609
|
+
if (name === "Form") {
|
|
610
|
+
await page.getByText("Form", { exact: true }).first().hover();
|
|
611
|
+
} else if (name === "Filter form") {
|
|
612
|
+
await page.getByText("Form", { exact: true }).nth(1).hover();
|
|
613
|
+
} else {
|
|
614
|
+
await page.getByText(name, { exact: true }).hover();
|
|
615
|
+
}
|
|
616
|
+
if (name === "Markdown") {
|
|
617
|
+
await page.getByRole("menuitem", { name: "Markdown" }).click();
|
|
618
|
+
} else {
|
|
619
|
+
await page.getByRole("menuitem", { name: "Users" }).click();
|
|
620
|
+
}
|
|
621
|
+
await page.mouse.move(300, 0);
|
|
622
|
+
}, "createBlockInPage");
|
|
623
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
624
|
+
0 && (module.exports = {
|
|
625
|
+
NocoPage,
|
|
626
|
+
createBlockInPage,
|
|
627
|
+
defineConfig,
|
|
628
|
+
expectInitializerMenu,
|
|
629
|
+
expectSettingsMenu,
|
|
630
|
+
omitSomeFields,
|
|
631
|
+
test,
|
|
632
|
+
...require("@playwright/test")
|
|
633
|
+
});
|
package/lib/e2e/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __copyProps = (to, from, except, desc) => {
|
|
6
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
7
|
+
for (let key of __getOwnPropNames(from))
|
|
8
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
9
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
10
|
+
}
|
|
11
|
+
return to;
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var e2e_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(e2e_exports);
|
|
17
|
+
__reExport(e2e_exports, require("./e2eUtils"), module.exports);
|
|
18
|
+
__reExport(e2e_exports, require("./templatesOfCollection"), module.exports);
|
|
19
|
+
__reExport(e2e_exports, require("./templatesOfPage"), module.exports);
|
|
20
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
21
|
+
0 && (module.exports = {
|
|
22
|
+
...require("./e2eUtils"),
|
|
23
|
+
...require("./templatesOfCollection"),
|
|
24
|
+
...require("./templatesOfPage")
|
|
25
|
+
});
|