I am trying to build something similar to puppeteer, but in C.
When page.waitForSelector is executed, I observe below messages are exchanged between puppeteer and devtools. I see total 5 requests sent by puppeteer and 5 responses from devtools as shown below.
I am not able to understand what happens in req1. It is sending one javascript. What is achieved by sending javascript to devtools. And executionContextId value is 4, where from puppeteer gets value 4.
Does it have any relation with addScriptToEvaluateOnNewDocument.
What is the actual use case , when addScriptToEvaluateOnNewDocument is used.
Please help me understanding this.
1. req1
--------------------------------------
{"sessionId":"1C18E8AED956A5DA393C88E73D76B255","method":"Runtime.callFunctionOn","params":{"functionDeclaration":"async function waitForPredicatePageFunction(predicateBody, polling, timeout, ...args) {\n const predicate = new Function('...args', predicateBody);\n let timedOut = false;\n if (timeout)\n setTimeout(() => timedOut = true, timeout);\n if (polling === 'raf')\n return await pollRaf();\n if (polling === 'mutation')\n return await pollMutation();\n if (typeof polling === 'number')\n return await pollInterval(polling);\n\n /**\n * @return {!Promise<*>}\n */\n function pollMutation() {\n const success = predicate.apply(null, args);\n if (success)\n return Promise.resolve(success);\n\n let fulfill;\n const result = new Promise(x => fulfill = x);\n const observer = new MutationObserver(mutations => {\n if (timedOut) {\n observer.disconnect();\n fulfill();\n }\n const success = predicate.apply(null, args);\n if (success) {\n observer.disconnect();\n fulfill(success);\n }\n });\n observer.observe(document, {\n childList: true,\n subtree: true,\n attributes: true\n });\n return result;\n }\n\n /**\n * @return {!Promise<*>}\n */\n function pollRaf() {\n let fulfill;\n const result = new Promise(x => fulfill = x);\n onRaf();\n return result;\n\n function onRaf() {\n if (timedOut) {\n fulfill();\n return;\n }\n const success = predicate.apply(null, args);\n if (success)\n fulfill(success);\n else\n requestAnimationFrame(onRaf);\n }\n }\n\n /**\n * @param {number} pollInterval\n * @return {!Promise<*>}\n */\n function pollInterval(pollInterval) {\n let fulfill;\n const result = new Promise(x => fulfill = x);\n onTimeout();\n return result;\n\n function onTimeout() {\n if (timedOut) {\n fulfill();\n return;\n }\n const success = predicate.apply(null, args);\n if (success)\n fulfill(success);\n else\n setTimeout(onTimeout, pollInterval);\n }\n }\n}\n//# sourceURL=__puppeteer_evaluation_script__\n","executionContextId":4,"arguments":[{"value":"return (function predicate(selectorOrXPath, isXPath, waitForVisible, waitForHidden) {\n const node = isXPath\n ? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue\n : document.querySelector(selectorOrXPath);\n if (!node)\n return waitForHidden;\n if (!waitForVisible && !waitForHidden)\n return node;\n const element = /** @type {Element} */ (node.nodeType === Node.TEXT_NODE ? node.parentElement : node);\n\n const style = window.getComputedStyle(element);\n const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox();\n const success = (waitForVisible === isVisible || waitForHidden === !isVisible);\n return success ? node : null;\n\n /**\n * @return {boolean}\n */\n function hasVisibleBoundingBox() {\n const rect = element.getBoundingClientRect();\n return !!(rect.top || rect.bottom || rect.width || rect.height);\n }\n })(...args)"},{"value":"mutation"},{"value":30000},{"value":"input[name=\"name\"]"},{"value":false},{"value":false},{"value":false}],"returnByValue":false,"awaitPromise":true,"userGesture":true},"id":18}
2. resp1
--------------------------------------
{"id":18,"result":{"result":{"type":"object","subtype":"node","className":"HTMLInputElement","description":"input#edit-name.form-text.required","objectId":"{\"injectedScriptId\":4,\"id\":1}"}},"sessionId":"1C18E8AED956A5DA393C88E73D76B255"}
3. req2
--------------------------------------
{"sessionId":"1C18E8AED956A5DA393C88E73D76B255","method":"Runtime.callFunctionOn","params":{"functionDeclaration":"s => !s\n//# sourceURL=__puppeteer_evaluation_script__\n","executionContextId":4,"arguments":[{"objectId":"{\"injectedScriptId\":4,\"id\":1}"}],"returnByValue":true,"awaitPromise":true,"userGesture":true},"id":19}
4. resp2
--------------------------------------
{"id":19,"result":{"result":{"type":"boolean","value":false}},"sessionId":"1C18E8AED956A5DA393C88E73D76B255"}
5. req3
--------------------------------------
{"sessionId":"1C18E8AED956A5DA393C88E73D76B255","method":"DOM.describeNode","params":{"objectId":"{\"injectedScriptId\":4,\"id\":1}"},"id":20}
6. resp3
--------------------------------------
{"id":20,"result":{"node":{"nodeId":0,"backendNodeId":44,"nodeType":1,"nodeName":"INPUT","localName":"input","nodeValue":"","childNodeCount":0,"attributes":["type","text","id","edit-name","name","name","value","","size","60","maxlength","60","class","form-text required"],"shadowRoots":[{"nodeId":0,"backendNodeId":45,"nodeType":11,"nodeName":"#document-fragment","localName":"","nodeValue":"","childNodeCount":1,"shadowRootType":"user-agent"}]}},"sessionId":"1C18E8AED956A5DA393C88E73D76B255"}
7. req4
--------------------------------------
{"sessionId":"1C18E8AED956A5DA393C88E73D76B255","method":"DOM.resolveNode","params":{"backendNodeId":44,"executionContextId":3},"id":21}
8. resp4
--------------------------------------
{"id":21,"result":{"object":{"type":"object","subtype":"node","className":"HTMLInputElement","description":"input#edit-name.form-text.required","objectId":"{\"injectedScriptId\":3,\"id\":2}"}},"sessionId":"1C18E8AED956A5DA393C88E73D76B255"}
9. req5
--------------------------------------
{"sessionId":"1C18E8AED956A5DA393C88E73D76B255","method":"Runtime.releaseObject","params":{"objectId":"{\"injectedScriptId\":4,\"id\":1}"},"id":22}
10. resp2
--------------------------------------
{"id":22,"result":{},"sessionId":"1C18E8AED956A5DA393C88E73D76B255"}
Thanks
Austin