@lvce-editor/test-worker 13.26.0 → 14.0.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 +25 -4
- package/dist/testWorkerMain.js +134 -24
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -28,15 +28,36 @@ interface ILocatorExternal {
|
|
|
28
28
|
readonly type: (text: string) => Promise<void>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
interface ParsedCssSelectorPart {
|
|
32
|
+
readonly selector: string;
|
|
33
|
+
readonly type: "css";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface ParsedTextSelectorPart {
|
|
37
|
+
readonly text: string;
|
|
38
|
+
readonly type: "text";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface ParsedHasTextSelectorPart {
|
|
42
|
+
readonly text: string;
|
|
43
|
+
readonly type: "has-text";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface ParsedNthSelectorPart {
|
|
47
|
+
readonly index: number;
|
|
48
|
+
readonly type: "nth";
|
|
49
|
+
}
|
|
50
|
+
export type ParsedSelectorPart = ParsedCssSelectorPart | ParsedTextSelectorPart | ParsedHasTextSelectorPart | ParsedNthSelectorPart;
|
|
51
|
+
export type ParsedCssSelector = readonly ParsedSelectorPart[];
|
|
52
|
+
|
|
31
53
|
interface ILocatorCreateOptions {
|
|
32
54
|
readonly hasText?: string;
|
|
33
55
|
readonly nth?: number;
|
|
34
56
|
}
|
|
35
57
|
export declare class Locator implements ILocatorExternal {
|
|
36
|
-
readonly _selector:
|
|
37
|
-
readonly
|
|
38
|
-
|
|
39
|
-
constructor(selector: any, { hasText, nth }?: ILocatorCreateOptions);
|
|
58
|
+
readonly _selector: string;
|
|
59
|
+
readonly _parsed: ParsedCssSelector;
|
|
60
|
+
constructor(selector: string, options?: ILocatorCreateOptions, parsed?: ParsedCssSelector);
|
|
40
61
|
click({ button }?: {
|
|
41
62
|
readonly button?: string;
|
|
42
63
|
}): Promise<void>;
|
package/dist/testWorkerMain.js
CHANGED
|
@@ -1218,7 +1218,9 @@ const get = id => {
|
|
|
1218
1218
|
};
|
|
1219
1219
|
|
|
1220
1220
|
const getLocatorInvoke = locator => {
|
|
1221
|
+
// @ts-ignore
|
|
1221
1222
|
if (locator.webViewId) {
|
|
1223
|
+
// @ts-ignore
|
|
1222
1224
|
const module = get(locator.webViewId);
|
|
1223
1225
|
return module.invoke;
|
|
1224
1226
|
}
|
|
@@ -1233,22 +1235,40 @@ const locatorInvoke = async (locator, method, ...params) => {
|
|
|
1233
1235
|
};
|
|
1234
1236
|
|
|
1235
1237
|
const printLocator = locator => {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1238
|
+
let result = '';
|
|
1239
|
+
for (const part of locator._parsed) {
|
|
1240
|
+
if (part.type === 'css') {
|
|
1241
|
+
if (!result) {
|
|
1242
|
+
result = part.selector;
|
|
1243
|
+
continue;
|
|
1244
|
+
}
|
|
1245
|
+
result = `${result} >> ${part.selector}`;
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
if (part.type === 'text') {
|
|
1249
|
+
if (!result) {
|
|
1250
|
+
result = `text=${part.text}`;
|
|
1251
|
+
continue;
|
|
1252
|
+
}
|
|
1253
|
+
result = `${result} text=${part.text}`;
|
|
1254
|
+
continue;
|
|
1255
|
+
}
|
|
1256
|
+
if (part.type === 'has-text') {
|
|
1257
|
+
result = `${result} "${part.text}"`;
|
|
1258
|
+
continue;
|
|
1259
|
+
}
|
|
1260
|
+
result = `${result}:nth(${part.index})`;
|
|
1241
1261
|
}
|
|
1242
|
-
return
|
|
1262
|
+
return result;
|
|
1243
1263
|
};
|
|
1244
1264
|
|
|
1245
1265
|
const toBeVisible = locator => {
|
|
1246
|
-
return `expected selector to be visible ${locator
|
|
1266
|
+
return `expected selector to be visible ${printLocator(locator)}`;
|
|
1247
1267
|
};
|
|
1248
1268
|
const toHaveValue = (locator, {
|
|
1249
1269
|
value
|
|
1250
1270
|
}) => {
|
|
1251
|
-
return `expected selector ${locator
|
|
1271
|
+
return `expected selector ${printLocator(locator)} to have value ${value}`;
|
|
1252
1272
|
};
|
|
1253
1273
|
const toHaveText = async (locator, options) => {
|
|
1254
1274
|
const locatorString = printLocator(locator);
|
|
@@ -1543,6 +1563,72 @@ const setMockRpc = mockRpc => {
|
|
|
1543
1563
|
state.mockRpcs[mockRpc.name] = mockRpc;
|
|
1544
1564
|
};
|
|
1545
1565
|
|
|
1566
|
+
class CssParsingError extends Error {
|
|
1567
|
+
constructor(message) {
|
|
1568
|
+
super(message);
|
|
1569
|
+
this.name = 'CssParsingError';
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
const startTokenRegex = /^[a-z][a-z0-9-]*/;
|
|
1574
|
+
const getStartToken = selector => {
|
|
1575
|
+
const match = selector.match(startTokenRegex);
|
|
1576
|
+
return match ? match[0] : '';
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
const htmlElements = ['a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdo', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', 'map', 'mark', 'menu', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'pre', 'progress', 'q', 'rp', 'rt', 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr'];
|
|
1580
|
+
|
|
1581
|
+
const isElement = selector => {
|
|
1582
|
+
return htmlElements.includes(selector);
|
|
1583
|
+
};
|
|
1584
|
+
|
|
1585
|
+
const isCssSelector = selector => {
|
|
1586
|
+
if (!selector) {
|
|
1587
|
+
return false;
|
|
1588
|
+
}
|
|
1589
|
+
if (selector.startsWith('.') || selector.startsWith('#') || selector.startsWith('[') || selector.startsWith('*') || selector.startsWith(':')) {
|
|
1590
|
+
return true;
|
|
1591
|
+
}
|
|
1592
|
+
const startToken = getStartToken(selector);
|
|
1593
|
+
if (!startToken) {
|
|
1594
|
+
return false;
|
|
1595
|
+
}
|
|
1596
|
+
return isElement(startToken);
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1599
|
+
const parseCssSelector = selector => {
|
|
1600
|
+
if (typeof selector !== 'string') {
|
|
1601
|
+
throw new TypeError('selector must be of type string');
|
|
1602
|
+
}
|
|
1603
|
+
if (selector.startsWith('text=')) {
|
|
1604
|
+
return [{
|
|
1605
|
+
text: selector.slice('text='.length),
|
|
1606
|
+
type: 'text'
|
|
1607
|
+
}];
|
|
1608
|
+
}
|
|
1609
|
+
if (selector.includes('text=')) {
|
|
1610
|
+
const index = selector.indexOf('text=');
|
|
1611
|
+
const cssSelector = selector.slice(0, index).trimEnd();
|
|
1612
|
+
if (!isCssSelector(cssSelector)) {
|
|
1613
|
+
throw new CssParsingError(`unsupported selector: ${selector}`);
|
|
1614
|
+
}
|
|
1615
|
+
return [{
|
|
1616
|
+
selector: cssSelector,
|
|
1617
|
+
type: 'css'
|
|
1618
|
+
}, {
|
|
1619
|
+
text: selector.slice(index + 'text='.length),
|
|
1620
|
+
type: 'text'
|
|
1621
|
+
}];
|
|
1622
|
+
}
|
|
1623
|
+
if (isCssSelector(selector)) {
|
|
1624
|
+
return [{
|
|
1625
|
+
selector,
|
|
1626
|
+
type: 'css'
|
|
1627
|
+
}];
|
|
1628
|
+
}
|
|
1629
|
+
throw new CssParsingError(`unsupported selector: ${selector}`);
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1546
1632
|
const performAction = async (locator, action, options) => {
|
|
1547
1633
|
const invoke = getLocatorInvoke(locator);
|
|
1548
1634
|
return invoke('TestFrameWork.performAction', locator, action, options);
|
|
@@ -1562,13 +1648,18 @@ const toButtonNumber = buttonType => {
|
|
|
1562
1648
|
};
|
|
1563
1649
|
|
|
1564
1650
|
class Locator {
|
|
1565
|
-
constructor(selector, {
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1651
|
+
constructor(selector, options = {}, parsed) {
|
|
1652
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
1653
|
+
throw new TypeError('options must be of type object');
|
|
1654
|
+
}
|
|
1655
|
+
const {
|
|
1656
|
+
hasText = '',
|
|
1657
|
+
nth = -1
|
|
1658
|
+
} = options;
|
|
1659
|
+
string(hasText, 'options.hasText must be of type string');
|
|
1660
|
+
number(nth, 'options.nth must be of type number');
|
|
1569
1661
|
this._selector = selector;
|
|
1570
|
-
this.
|
|
1571
|
-
this._hasText = hasText;
|
|
1662
|
+
this._parsed = parsed || applyLocatorOptions(parseCssSelector(selector), options);
|
|
1572
1663
|
}
|
|
1573
1664
|
async click({
|
|
1574
1665
|
button = 'left'
|
|
@@ -1589,20 +1680,15 @@ class Locator {
|
|
|
1589
1680
|
return performAction(this, 'hover', options);
|
|
1590
1681
|
}
|
|
1591
1682
|
first() {
|
|
1592
|
-
return new Locator(this._selector, {
|
|
1593
|
-
nth: 0
|
|
1594
|
-
});
|
|
1683
|
+
return new Locator(this._selector, {}, withNth(this._parsed, 0));
|
|
1595
1684
|
}
|
|
1596
1685
|
locator(subSelector) {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
}
|
|
1600
|
-
return new Locator(`${this._selector} ${subSelector}`);
|
|
1686
|
+
const selector = `${this._selector} ${subSelector}`;
|
|
1687
|
+
return new Locator(selector, {}, [...this._parsed, ...parseCssSelector(subSelector)]);
|
|
1601
1688
|
}
|
|
1602
1689
|
nth(nth) {
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
});
|
|
1690
|
+
number(nth, 'nth must be of type number');
|
|
1691
|
+
return new Locator(this._selector, {}, withNth(this._parsed, nth));
|
|
1606
1692
|
}
|
|
1607
1693
|
async type(text) {
|
|
1608
1694
|
const options = {
|
|
@@ -1617,8 +1703,32 @@ class Locator {
|
|
|
1617
1703
|
});
|
|
1618
1704
|
}
|
|
1619
1705
|
}
|
|
1706
|
+
const applyLocatorOptions = (parsed, {
|
|
1707
|
+
hasText = '',
|
|
1708
|
+
nth = -1
|
|
1709
|
+
}) => {
|
|
1710
|
+
let nextParsed = parsed;
|
|
1711
|
+
if (hasText) {
|
|
1712
|
+
nextParsed = [...nextParsed, {
|
|
1713
|
+
text: hasText,
|
|
1714
|
+
type: 'has-text'
|
|
1715
|
+
}];
|
|
1716
|
+
}
|
|
1717
|
+
if (nth !== -1) {
|
|
1718
|
+
nextParsed = withNth(nextParsed, nth);
|
|
1719
|
+
}
|
|
1720
|
+
return nextParsed;
|
|
1721
|
+
};
|
|
1722
|
+
const withNth = (parsed, nth) => {
|
|
1723
|
+
const filtered = parsed.filter(part => part.type !== 'nth');
|
|
1724
|
+
return [...filtered, {
|
|
1725
|
+
index: nth,
|
|
1726
|
+
type: 'nth'
|
|
1727
|
+
}];
|
|
1728
|
+
};
|
|
1620
1729
|
|
|
1621
1730
|
const createLocator = (selector, options = {}) => {
|
|
1731
|
+
string(selector, 'selector must be of type string');
|
|
1622
1732
|
return new Locator(selector, options);
|
|
1623
1733
|
};
|
|
1624
1734
|
|