@lvce-editor/test-worker 6.1.0 → 6.3.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/dist/api.d.ts CHANGED
@@ -1,4 +1,34 @@
1
1
 
2
+ export interface LocatorExpect {
3
+ /**
4
+ * @internal
5
+ */
6
+ negated: boolean;
7
+ /**
8
+ * @internal
9
+ */
10
+ readonly checkSingleElementCondition: (fnName: string, options?: any) => Promise<void>;
11
+ /**
12
+ * @internal
13
+ */
14
+ readonly checkMultiElementCondition: (fnName: string, options: any) => Promise<void>;
15
+ readonly toBeVisible: () => Promise<void>;
16
+ readonly toHaveText: (text: string) => Promise<void>;
17
+ readonly toContainText: (text: string) => Promise<void>;
18
+ readonly toHaveValue: (value: string) => Promise<void>;
19
+ readonly toBeFocused: () => Promise<void>;
20
+ readonly toHaveCSS: (key: string, value: string) => Promise<void>;
21
+ readonly toHaveAttribute: (key: string, value: string) => Promise<void>;
22
+ readonly toHaveJSProperty: (key: string, value: any) => Promise<void>;
23
+ readonly toHaveClass: (className: string) => Promise<void>;
24
+ readonly toHaveId: (id: string) => Promise<void>;
25
+ readonly toHaveCount: (count: number) => Promise<void>;
26
+ readonly toBeHidden: () => Promise<void>;
27
+ readonly not: LocatorExpect;
28
+ }
29
+
30
+
31
+
2
32
  interface LocatorClickOptions {
3
33
  readonly button?: string;
4
34
  }
@@ -27,6 +57,7 @@ export interface FileSystemTmpDirOptions {
27
57
 
28
58
  interface Workspace {
29
59
  readonly openTmpDir: () => Promise<string>;
60
+ readonly resolveFileUrl: (url: string) => string;
30
61
  readonly setPath: (path: string) => Promise<void>;
31
62
  }
32
63
 
@@ -513,7 +544,7 @@ export interface TestApi {
513
544
  readonly TitleBarMenuBar: TitleBarMenuBar
514
545
  readonly Url: Url
515
546
  readonly WebView: WebView
516
- readonly expect: any
547
+ readonly expect: (locator: ILocatorExternal) => LocatorExpect
517
548
  readonly Locator: (selector: string, option?: any) => ILocatorExternal
518
549
  }
519
550
 
@@ -1079,10 +1079,55 @@ const sendMessagePortToEditorWorker = async (port, rpcId) => {
1079
1079
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToEditorWorker', port, command, rpcId);
1080
1080
  };
1081
1081
 
1082
+ const callFunction = async (fn, args) => {
1083
+ try {
1084
+ await fn(args);
1085
+ return undefined;
1086
+ } catch (error) {
1087
+ return error;
1088
+ }
1089
+ };
1090
+
1082
1091
  const formatDuration = duration => {
1083
1092
  return duration.toFixed(2) + 'ms';
1084
1093
  };
1085
1094
 
1095
+ const Fail = 'fail';
1096
+ const Pass = 'pass';
1097
+
1098
+ const executeTest2 = async (name, fn, globals, timestampGenerator) => {
1099
+ const getTimestamp = timestampGenerator;
1100
+ const start = getTimestamp();
1101
+ const error = await callFunction(fn, globals);
1102
+ const end = getTimestamp();
1103
+ const duration = end - start;
1104
+ const formattedDuration = formatDuration(duration);
1105
+ if (error) {
1106
+ return {
1107
+ error,
1108
+ start,
1109
+ end,
1110
+ duration,
1111
+ formattedDuration,
1112
+ name,
1113
+ type: Fail,
1114
+ background: 'red',
1115
+ text: `test failed: ${error}`
1116
+ };
1117
+ }
1118
+ return {
1119
+ error: undefined,
1120
+ start,
1121
+ end,
1122
+ duration,
1123
+ formattedDuration,
1124
+ name,
1125
+ type: Pass,
1126
+ background: 'green',
1127
+ text: `test passed in ${formattedDuration}`
1128
+ };
1129
+ };
1130
+
1086
1131
  const printError = error => {
1087
1132
  if (error && error.constructor.name === 'AssertionError') {
1088
1133
  console.error(error.message);
@@ -1096,66 +1141,26 @@ const printTestError = async error => {
1096
1141
  printError(error);
1097
1142
  };
1098
1143
 
1099
- const stringifyError = error => {
1100
- if (!error) {
1101
- return `${error}`;
1102
- }
1103
- if (error && error.message && error.constructor.name && error.constructor.name !== 'Error' && error.constructor.name !== 'VError') {
1104
- return `${error}`;
1105
- }
1106
- return `${error.message}`;
1107
- };
1108
-
1109
- const Fail = 'fail';
1110
- const Pass = 'pass';
1111
-
1112
1144
  const now = () => {
1113
1145
  return performance.now();
1114
1146
  };
1115
1147
 
1116
- // TODO make this code more functional, returning a test result
1117
- // and a separate function prints out the test result
1118
1148
  const executeTest = async (name, fn, globals = {}) => {
1119
- let _error;
1120
- let _start;
1121
- let _end;
1122
- let _duration;
1123
- let _formattedDuration;
1124
- try {
1125
- _start = now();
1126
- await fn(globals);
1127
- _end = now();
1128
- _duration = _end - _start;
1129
- _formattedDuration = formatDuration(_duration);
1130
- // eslint-disable-next-line no-console
1131
- console.info(`PASS ${name} in ${_formattedDuration}`);
1132
- } catch (error) {
1133
- if (error &&
1134
- // @ts-ignore
1135
- error.message.startsWith('Failed to load command TestFrameWork.')) {
1136
- console.error(error);
1137
- return;
1138
- }
1139
- _error = stringifyError(error);
1140
- if (!(error instanceof VError)) {
1141
- error = new VError(error, `Test failed: ${name}`);
1142
- }
1149
+ const {
1150
+ error,
1151
+ formattedDuration,
1152
+ background,
1153
+ text,
1154
+ type
1155
+ } = await executeTest2(name, fn, globals, now);
1156
+ if (error) {
1143
1157
  await printTestError(error);
1144
- }
1145
- let state;
1146
- let background;
1147
- let text;
1148
- if (_error) {
1149
- state = Fail;
1150
- background = 'red';
1151
- text = `test failed: ${_error}`;
1152
1158
  } else {
1153
- background = 'green';
1154
- text = `test passed in ${_formattedDuration}`;
1155
- state = Pass;
1159
+ // eslint-disable-next-line no-console
1160
+ console.info(`PASS ${name} in ${formattedDuration}`);
1156
1161
  }
1157
1162
  // @ts-ignore
1158
- await invoke$1('TestFrameWork.showOverlay', state, background, text);
1163
+ await invoke$1('TestFrameWork.showOverlay', type, background, text);
1159
1164
  };
1160
1165
 
1161
1166
  const importScript = async url => {
@@ -1240,6 +1245,20 @@ const toHaveText = async (locator, options) => {
1240
1245
  }
1241
1246
  return `expected selector ${locatorString} to have text "${text}" but was "${actual}"`;
1242
1247
  };
1248
+ const toContainText = async (locator, options) => {
1249
+ const locatorString = printLocator(locator);
1250
+ const {
1251
+ wasFound,
1252
+ actual
1253
+ } = await locatorInvoke(locator, 'TestFrameWork.checkConditionError', 'toContainText', locator, options);
1254
+ const {
1255
+ text
1256
+ } = options;
1257
+ if (!wasFound) {
1258
+ return `expected selector ${locatorString} to contain text "${text}" element was not found`;
1259
+ }
1260
+ return `expected selector ${locatorString} to contain text "${text}" but was "${actual}"`;
1261
+ };
1243
1262
  const toHaveAttribute = async (locator, options) => {
1244
1263
  const locatorString = printLocator(locator);
1245
1264
  const {
@@ -1341,6 +1360,8 @@ const getFunction = fnName => {
1341
1360
  return toHaveValue;
1342
1361
  case 'toHaveText':
1343
1362
  return toHaveText;
1363
+ case 'toContainText':
1364
+ return toContainText;
1344
1365
  case 'toHaveAttribute':
1345
1366
  return toHaveAttribute;
1346
1367
  case 'toHaveCount':
@@ -3503,6 +3524,12 @@ const setWebViewPort = async (uid, port, origin, portType) => {
3503
3524
  await invokeAndTransfer('WebView.setPort', uid, port, origin, portType);
3504
3525
  };
3505
3526
 
3527
+ const transferWebViewPort = async (webViewId, port) => {
3528
+ const info = await getWebViewInfo(webViewId);
3529
+ const portType = 'test';
3530
+ await setWebViewPort(info.uid, port, info.origin, portType);
3531
+ };
3532
+
3506
3533
  const waitForFirstEventEvent = async port => {
3507
3534
  const {
3508
3535
  resolve,
@@ -3521,9 +3548,7 @@ const createPortRpc = async webViewId => {
3521
3548
  } = getPortTuple();
3522
3549
  const firstEventPromise = waitForFirstEventEvent(port1);
3523
3550
  // TODO ask extension host worker about webview uid
3524
- const info = await getWebViewInfo(webViewId);
3525
- const portType = 'test';
3526
- await setWebViewPort(info.uid, port2, info.origin, portType);
3551
+ await transferWebViewPort(webViewId, port2);
3527
3552
  const firstEvent = await firstEventPromise;
3528
3553
  if (firstEvent.data !== 'ready') {
3529
3554
  throw new Error('unexpected first message');
@@ -3554,6 +3579,16 @@ const TestFrameWorkComponentWebView = {
3554
3579
  fromId
3555
3580
  };
3556
3581
 
3582
+ const toFileUrl = url => {
3583
+ const urlObject = new URL(url);
3584
+ const pathName = urlObject.pathname;
3585
+ if (!pathName.startsWith('/remote')) {
3586
+ throw new Error(`url must start with /remote`);
3587
+ }
3588
+ const rest = pathName.slice('/remote'.length);
3589
+ return `file://${rest}`;
3590
+ };
3591
+
3557
3592
  const setPath = async path => {
3558
3593
  await invoke$1('Workspace.setPath', path);
3559
3594
  };
@@ -3562,10 +3597,20 @@ const openTmpDir = async () => {
3562
3597
  await setPath(tmpDir);
3563
3598
  return tmpDir;
3564
3599
  };
3600
+ const resolveFileUrl = url => {
3601
+ // TODO in web, convert to memfs or fetch url
3602
+ // TODO on web: read filemap for that fixture
3603
+ // else, use filesystem to read the files
3604
+ // TODO covert remote url to file url
3605
+ // then set that as workspace path
3606
+
3607
+ return toFileUrl(url);
3608
+ };
3565
3609
 
3566
3610
  const TestFrameWorkComponentWorkspace = {
3567
3611
  __proto__: null,
3568
3612
  openTmpDir,
3613
+ resolveFileUrl,
3569
3614
  setPath
3570
3615
  };
3571
3616
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/test-worker",
3
- "version": "6.1.0",
3
+ "version": "6.3.0",
4
4
  "description": "Test Worker",
5
5
  "repository": {
6
6
  "type": "git",