ulixee / hero

The web browser built for scraping
MIT License
647 stars 32 forks source link

"Cannot find context with specified id" when showChrome=true #263

Open eNcacz opened 1 month ago

eNcacz commented 1 month ago

I think I have found a buggy behavior of ulixee browser when we work with frames. I use the version 2.0.0-alpha.28.

To reproduce the bug, you need these two html files:

browserFrameTestParent.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Testcase</title>
</head>
<body>
    <h1>Main Page</h1>
    <iframe id="testFrame" src="browserFrameTestFrame.html"></iframe>
    <br />
    <img src="doesntmatter.png"> <!-- without this element we get different error: Timeout waiting for navigation "JavascriptReady" -->
</body>
</html>

browserFrameTestFrame.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Scraper test page for Browser frame methods</title>
</head>
<body>
    <h2>This is the Frame Page 1</h2>
    <a id="changeTopDocument" href="browserFindElement.html" target="_top">Change whole page, not only the frame.</a>
</body>
</html>

And this is the test script:

import Hero from '@ulixee/hero-playground'
import assert from "node:assert"

process.on('unhandledRejection', (reason, promise) => {
    if (reason instanceof Error) {
        console.error(`Unhandled Rejection: ${reason}`, {stack: reason.stack})
    } else {
        console.error(`Unhandled Rejection: ${reason}`)
    }
    process.exit(1)
});

(async () => {
    const hero = new Hero({showChrome: true})

    await hero.goto('http://localhost/~vaclav/ulixee/browserFrameTestParent.html')  // <- change this url
    await hero.waitForPaintingStable()

    await hero.goto('http://localhost/~vaclav/ulixee/browserFrameTestParent.html?test=1')  //<- change this url; keep the query parameter - it is important here
    await hero.waitForPaintingStable()

    const frameElem = await hero.mainFrameEnvironment.document.getElementById('testFrame')

    const frame2 = await hero.mainFrameEnvironment.getFrameEnvironment(frameElem)
    assert(frame2 !== null)

    console.log('So far so good.')
    await frame2.document.getElementById('changeTopDocument')
    console.log('This will not be printed. The application crash on the line above.')

    await hero.close()
    console.log('Done')
})();

When I run the script, then the output looks like this:

Started Ulixee Cloud at localhost:1818
So far so good.
2024-05-21T11:28:50.881Z ERROR [hero-core/connections/ConnectionToHeroClient] ConnectionToClient.HandleRequestError {
  context: {},
  sessionId: 'OLznhTkUkpMU92gUwJ0aS',
  sessionName: undefined
} ProtocolError: Runtime.callFunctionOn: Cannot find context with specified id
  at new Resolvable (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/Resolvable.ts:19:18)
    at createPromise (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/utils.ts:140:10)
    at DevtoolsSession.send (/home/vaclav/sandbox/ulixee/agent/main/lib/DevtoolsSession.ts:82:37)
    at Frame.evaluateOnNode (/home/vaclav/sandbox/ulixee/agent/main/lib/Frame.ts:488:49)
    at Frame.getContainerOffset (/home/vaclav/sandbox/ulixee/agent/main/lib/Frame.ts:424:47)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async JsPath.exec (/home/vaclav/sandbox/ulixee/agent/main/lib/JsPath.ts:69:29)
    at async FrameEnvironment.execJsPath (/home/vaclav/sandbox/ulixee/node_modules/core/lib/FrameEnvironment.ts:246:12)
    at async CommandRecorder.runCommandFn (/home/vaclav/sandbox/ulixee/node_modules/core/lib/CommandRecorder.ts:90:16)
    at async CommandRunner.runFn (/home/vaclav/sandbox/ulixee/node_modules/core/lib/CommandRunner.ts:36:14) {
  method: 'Runtime.callFunctionOn',
  remoteError: { code: -32000, message: 'Cannot find context with specified id' }
}
Unhandled Rejection: ProtocolError: Runtime.callFunctionOn: Cannot find context with specified id {
  stack: '\n' +
    '\n' +
    "  --->  await frame2.document.getElementById('changeTopDocument')\n" +
    '\n' +
    '\n' +
    'ProtocolError: Runtime.callFunctionOn: Cannot find context with specified id\n' +
    '  at new Resolvable (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/Resolvable.ts:19:18)\n' +
    '    at createPromise (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/utils.ts:140:10)\n' +
    '    at DevtoolsSession.send (/home/vaclav/sandbox/ulixee/agent/main/lib/DevtoolsSession.ts:82:37)\n' +
    '    at Frame.evaluateOnNode (/home/vaclav/sandbox/ulixee/agent/main/lib/Frame.ts:488:49)\n' +
    '    at Frame.getContainerOffset (/home/vaclav/sandbox/ulixee/agent/main/lib/Frame.ts:424:47)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async JsPath.exec (/home/vaclav/sandbox/ulixee/agent/main/lib/JsPath.ts:69:29)\n' +
    '    at async FrameEnvironment.execJsPath (/home/vaclav/sandbox/ulixee/node_modules/core/lib/FrameEnvironment.ts:246:12)\n' +
    '    at async CommandRecorder.runCommandFn (/home/vaclav/sandbox/ulixee/node_modules/core/lib/CommandRecorder.ts:90:16)\n' +
    '    at async CommandRunner.runFn (/home/vaclav/sandbox/ulixee/node_modules/core/lib/CommandRunner.ts:36:14)\n' +
    '------REMOTE CORE---------------------------------\n' +
    '  at Function.reviver (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/TypeSerializer.ts:249:26)\n' +
    '    at JSON.parse (<anonymous>)\n' +
    '    at Function.parse (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/TypeSerializer.ts:31:17)\n' +
    '    at WsTransportToCore.onMessage (/home/vaclav/sandbox/ulixee/node_modules/net/lib/WsTransportToCore.ts:105:36)\n' +
    '    at WebSocket.emit (node:events:517:28)\n' +
    '    at Receiver.receiverOnMessage (/home/vaclav/sandbox/ulixee/node_modules/ws/lib/websocket.js:1068:20)\n' +
    '    at Receiver.emit (node:events:517:28)\n' +
    '    at Receiver.dataMessage (/home/vaclav/sandbox/ulixee/node_modules/ws/lib/receiver.js:517:14)\n' +
    '    at /home/vaclav/sandbox/ulixee/node_modules/ws/lib/receiver.js:468:23\n' +
    '    at /home/vaclav/sandbox/ulixee/node_modules/ws/lib/permessage-deflate.js:308:9\n' +
    '------CONNECTION----------------------------------\n' +
    '  at new Resolvable (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/Resolvable.ts:19:18)\n' +
    '    at createPromise (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/utils.ts:140:10)\n' +
    '    at PendingMessages.create (/home/vaclav/sandbox/ulixee/node_modules/net/lib/PendingMessages.ts:47:44)\n' +
    '    at ConnectionToHeroCore.sendRequest (/home/vaclav/sandbox/ulixee/node_modules/net/lib/ConnectionToCore.ts:158:50)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async CoreCommandQueue.sendRequest (/home/vaclav/sandbox/ulixee/node_modules/client/lib/CoreCommandQueue.ts:317:12)\n' +
    '    at async Object.cb (/home/vaclav/sandbox/ulixee/node_modules/client/lib/CoreCommandQueue.ts:231:16)\n' +
    '    at async Queue.next (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/Queue.ts:188:19)\n' +
    '------CORE COMMANDS-------------------------------\n' +
    '    at Queue.run (/home/vaclav/sandbox/ulixee/node_modules/commons/lib/Queue.ts:63:19)\n' +
    '    at CoreCommandQueue.run (/home/vaclav/sandbox/ulixee/node_modules/client/lib/CoreCommandQueue.ts:220:8)\n' +
    '    at CoreFrameEnvironment.execJsPath (/home/vaclav/sandbox/ulixee/node_modules/client/lib/CoreFrameEnvironment.ts:80:36)\n' +
    '    at execJsPath (/home/vaclav/sandbox/ulixee/node_modules/client/lib/SetupAwaitedHandler.ts:160:26)\n' +
    '    at Object.createNodePointer (/home/vaclav/sandbox/ulixee/node_modules/client/lib/SetupAwaitedHandler.ts:77:24)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async AwaitedHandler.createNodePointer (/home/vaclav/sandbox/ulixee/node_modules/files/2-finalized/awaited-dom/base/AwaitedHandler.ts:33:12)\n' +
    '    at async NodeFactory.createInstanceWithNodePointer (/home/vaclav/sandbox/ulixee/node_modules/files/2-finalized/awaited-dom/base/NodeFactory.ts:23:19)\n' +
    '    at async /home/vaclav/sandbox/ulixee/app.ts:28:5\n' +
    '\n' +
    '--------------------------------------------------\n' +
    '--------------------------------------------------\n' +
    '------OLznhTkUkpMU92gUwJ0aS-----------------------\n' +
    '--------------------------------------------------'
}

Process finished with exit code 1
eNcacz commented 1 month ago

A small update.

The testcase above is simplified version of my complex project, where I found the bug originally. In this small test case it is enough to switch showChrome to false and the issue disappears. But it is not true in the original project - the issue persists there even if I switch showChrome to false. I'm writing this note here to be clear that the bug can appear regardless the showChrome is true or false.

blakebyrnes commented 1 month ago

Thanks for the test case and info. Will take a look

eNcacz commented 3 weeks ago

Hi, is there any chance you'll have time to check it out?