Puppeteer в Windows: щелчок якоря при нажатой мета-клавише не откроет ссылку в новой вкладке, как ожидалось - PullRequest
0 голосов
/ 25 мая 2019

Цель состоит в том, чтобы щелкнуть привязку, просто подведя к ней мышку и выполнив щелчок в текущей позиции курсора мыши (которая, будем надеяться, будет в интерактивной области ссылки), вместе с нажатой клавишей Meta (Command on Mac OS, Ctrl в Windows).

Ожидаемый результат - Chrome откроет новую вкладку, загружая связанную страницу. Это прекрасно работает на Mac OS. Но в Windows он просто загружает страницу на текущей вкладке, как если бы во время щелчка не удерживалось нажатие клавиши Ctrl.

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: false,
        executablePath: process.platform === "darwin" ?
            "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
            // Location of Chrome for Windows Canary v76.x on my Windows system, yours may vary
            : "C:\\Users\\ADMINI~1\\AppData\\Local\\Google\\CHROME~2\\APPLIC~1\\chrome.exe"

    });
    const page = await browser.newPage();
    await page.goto("https://example.com", { waitUntil: 'networkidle0', timeout: 30000 });
    let mySelector = "a";
    let myElems = await page.evaluate(function(myThis) {
        const domElemA = Array.from(document.querySelectorAll(myThis.selector));
        const outElemA = domElemA.reduce(function(acc, cur) {
            let r = cur.getBoundingClientRect();
            let myObj = { rectLeft: Math.round(r.left), rectTop: Math.round(r.top), rectRight: Math.round(r.right), rectBottom: Math.round(r.bottom) };
            // optionally do some filtering here, for objects outside the viewport.
            // I know I could use Array.map() here if no filtering desired.
            return [...acc, myObj];
        }, []);
        return outElemA;
    }, { selector: mySelector });
    console.log(myElems);   // output the anchors we found
    let e = myElems[0];
    // determine the center of the anchor element
    let x = Math.round((e.rectRight - e.rectLeft) / 2 + e.rectLeft);
    let y = Math.round((e.rectBottom - e.rectTop) / 2 + e.rectTop);
    let k = "Meta"  // Command on MacOS, Ctrl on Windows
    await page.mouse.move(x, y);
    await page.waitFor(100);
    await page.keyboard.down(k);
    await page.waitFor(100);
    await page.mouse.down();
    await page.waitFor(100);
    await page.mouse.up();
    await page.waitFor(100);
    await page.keyboard.up(k);
    // Expected result: Link is opened in new tab due to Meta key held down while clicking
    // Actual result on Mac OS: Behaves as expected
    // Actual result on Windows: Opens link in the same tab, as if no Meta key were pressed
})();

Версия кукловода:

> npm view puppeteer
puppeteer@1.17.0 | Apache-2.0 | deps: 8 | versions: 642

Версия Chrome для Windows (канарейка):

76.0.3803.0 (Official Build) (64-bit) 

Я понимаю, что есть удобные функции Puppeteer, такие как page.click (), которые щелкают прямо в центр данного элемента, но любые такие быстрые решения выходят за рамки этого вопроса.

Он должен работать, не выбирая элемент напрямую, переместив курсор в вероятную активируемую зону и затем щелкнув мышью. Я знаю, что эта кликабельная форма может варьироваться, поэтому такой подход может потерпеть неудачу - также не тот тип совета, который я прошу («Зачем вам это делать !?»). ?

Кроме того, это не дубликат часто звучащей жалобы на то, что Meta + A (выбрать все) отлично работает в Windows, но не работает должным образом в Mac OS.

Но я подозреваю, что это аналогичная проблема, но наоборот, в зависимости от того, где обрабатываются события GUI, на уровне модели DOM, на уровне браузера, на уровне ОС.

Если проблема носит неустранимый характер, есть ли обходной путь, чтобы открыть ссылку в новой вкладке, но на 100% основанную на текущем положении мыши, и ничего не делать "непосредственно" с целевым элементом DOM напрямую? Page.click () и тому подобное делают много «вещей», которые я не хочу, чтобы мой «пользователь» делал.

1 Ответ

1 голос
/ 25 мая 2019

Вероятно, это связано с тем, что клавиша meta ссылается на клавишу "Windows" в Windows.

Вы можете использовать ctrl, если она работает в Windows:

let k = process.platform == "win32" ? "Control" : "Meta";

https://nodejs.org/api/process.html#process_process_platform

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...