chore: do not use Array.from in injected script (#6876)
This method is most often overridden by some bad polyfill that does not work correctly and breaks `$eval` and `$$eval` methods. As a best-effort fix, use a `[...iterable]` throughout the code.
This commit is contained in:
parent
f2cc439d8b
commit
d4482f3ad3
|
|
@ -124,7 +124,7 @@ export class InjectedScript {
|
|||
}
|
||||
set = newSet;
|
||||
}
|
||||
let result = Array.from(set) as Element[];
|
||||
let result = [...set] as Element[];
|
||||
if (partsToCheckOne.length) {
|
||||
const partial = { parts: partsToCheckOne };
|
||||
result = result.filter(e => !!this._querySelectorRecursively(e, partial, 0));
|
||||
|
|
@ -448,7 +448,7 @@ export class InjectedScript {
|
|||
if (element.nodeName.toLowerCase() !== 'select')
|
||||
return 'error:notselect';
|
||||
const select = element as HTMLSelectElement;
|
||||
const options = Array.from(select.options);
|
||||
const options = [...select.options];
|
||||
const selectedOptions = [];
|
||||
let remainingOptionsToSelect = optionsToSelect.slice();
|
||||
for (let index = 0; index < options.length; index++) {
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ export class SelectorEvaluatorImpl implements SelectorEvaluator {
|
|||
this._engines.set('near', createPositionEngine('near', boxNear));
|
||||
this._engines.set('nth-match', nthMatchEngine);
|
||||
|
||||
const allNames = Array.from(this._engines.keys());
|
||||
const allNames = [...this._engines.keys()];
|
||||
allNames.sort();
|
||||
const parserNames = Array.from(customCSSNames).slice();
|
||||
const parserNames = [...customCSSNames];
|
||||
parserNames.sort();
|
||||
if (allNames.join('|') !== parserNames.join('|'))
|
||||
throw new Error(`Please keep customCSSNames in sync with evaluator engines: ${allNames.join('|')} vs ${parserNames.join('|')}`);
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element): Se
|
|||
const parent = element.parentNode as (Element | ShadowRoot);
|
||||
|
||||
// Combine class names until unique.
|
||||
const classes = Array.from(element.classList);
|
||||
const classes = [...element.classList];
|
||||
for (let i = 0; i < classes.length; ++i) {
|
||||
const token = '.' + classes.slice(0, i + 1).join('.');
|
||||
const selector = uniqueCSSSelector(token);
|
||||
|
|
@ -261,7 +261,7 @@ function cssFallback(injectedScript: InjectedScript, targetElement: Element): Se
|
|||
|
||||
// Ordinal is the weakest signal.
|
||||
if (parent) {
|
||||
const siblings = Array.from(parent.children);
|
||||
const siblings = [...parent.children];
|
||||
const sameTagSiblings = siblings.filter(sibling => (sibling).nodeName.toLowerCase() === nodeName);
|
||||
const token = sameTagSiblings.indexOf(element) === 0 ? nodeName : `${nodeName}:nth-child(${1 + siblings.indexOf(element)})`;
|
||||
const selector = uniqueCSSSelector(token);
|
||||
|
|
|
|||
|
|
@ -74,3 +74,12 @@ it('should return complex values', async ({page, server}) => {
|
|||
const texts = await page.$$eval('css=div', divs => divs.map(div => div.textContent));
|
||||
expect(texts).toEqual(['hello', 'beautiful', 'world!']);
|
||||
});
|
||||
|
||||
it('should work with bogus Array.from', async ({page, server}) => {
|
||||
await page.setContent('<div>hello</div><div>beautiful</div><div>world!</div>');
|
||||
await page.evaluate(() => {
|
||||
Array.from = () => [];
|
||||
});
|
||||
const divsCount = await page.$$eval('css=div', divs => divs.length);
|
||||
expect(divsCount).toBe(3);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue