[{"data":1,"prerenderedAt":1334},["ShallowReactive",2],{"SiteFooter_cLEacilcm59lTjFJjLY6mXNWLL0ETtzOIiZwIHgDpy0":3,"doc-\u002Fdocs\u002Fextending\u002Fjavascript-extensions":17,"docs-nav":1236,"nav-compare":1310,"editor-3p7gep":1320,"editor-1tnku7v":1322,"editor-ued5q9":1324,"editor-hkvr3d":1326,"editor-cpc3it":1328,"editor-1jftwva":1330,"editor-iahx3t":1332},["Island",4],{"key":5,"result":6},"SiteFooter_cLEacilcm59lTjFJjLY6mXNWLL0ETtzOIiZwIHgDpy0",{"head":7},{"style":8},[9,11,13,15],{"innerHTML":10},".site-footer[data-v-8bb1d4ae]{border-top:1px solid var(--line);background:var(--chrome);padding:var(--sp-8) var(--gutter) var(--sp-10);gap:var(--sp-6);flex-direction:column;display:flex}.links[data-v-8bb1d4ae]{gap:var(--sp-4);grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));max-width:62rem;display:grid}.links a[data-v-8bb1d4ae]{align-items:flex-start;gap:var(--sp-3);padding:var(--sp-3);border-bottom:1px solid var(--line);border-radius:var(--radius-sm);background:var(--panel);color:var(--ink);border:1px solid var(--line);display:flex}.links a[data-v-8bb1d4ae]:focus-visible,.links a[data-v-8bb1d4ae]:hover{border-color:var(--line-strong)}.links[data-v-8bb1d4ae] .mark,.links[data-v-8bb1d4ae] .rf-mark{width:1.35rem;height:1.35rem;color:var(--dim);flex:none;margin-top:.1rem}.links a[data-v-8bb1d4ae]:hover .mark,.links a[data-v-8bb1d4ae]:hover .rf-mark{color:var(--red)}.links span[data-v-8bb1d4ae]{flex-direction:column;gap:2px;min-width:0;display:flex}.links b[data-v-8bb1d4ae]{font-family:var(--font-display);font-size:.85rem;font-weight:400}.links small[data-v-8bb1d4ae]{color:var(--faint);font-size:.78rem}.colophon[data-v-8bb1d4ae]{color:var(--faint);margin:0;font-size:.75rem}@supports (corner-shape:bevel){.links a[data-v-8bb1d4ae]{corner-shape:bevel}}",{"innerHTML":12},".mark[data-v-cc0d96a5]{vertical-align:-.125em;flex:none;width:1em;height:1em}",{"innerHTML":14},".mark[data-v-26f5673d]{vertical-align:-.125em;flex:none;width:1em;height:1em}",{"innerHTML":16},".rf-mark[data-v-26317b3e]{fill:currentColor;stroke:none;flex:none}",{"id":18,"title":19,"body":20,"description":1228,"extension":1229,"meta":1230,"navigation":126,"order":110,"path":1231,"section":1232,"seo":1233,"stem":1234,"__hash__":1235},"docs\u002Fdocs\u002Fextending\u002Fjavascript-extensions.md","JavaScript extensions",{"type":21,"value":22,"toc":1215},"minimark",[23,32,58,63,423,426,472,477,480,571,591,601,616,626,632,678,682,685,853,887,916,920,923,927,934,939,942,950,957,1056,1069,1073,1145,1149,1184,1187,1191,1195,1199,1208,1211],[24,25,26,27,31],"p",{},"A JavaScript module adds keywords that run on the Node side, with the Playwright\n",[28,29,30],"code",{},"page"," object in hand. It is the lighter of the two extension points: no Python,\nno class, just exported functions.",[24,33,34,35,38,39,41,42,45,46,49,50,53,54,57],{},"Browser loads the module with ",[28,36,37],{},"require()",". CommonJS is the safe default and what\nthe library's own tests use, but on the Node versions Browser supports ",[28,40,37],{},"\nalso loads ESM, so ",[28,43,44],{},"export","\u002F",[28,47,48],{},"import"," works. The one thing it cannot load is an\nESM module using top-level ",[28,51,52],{},"await",", which fails with ",[28,55,56],{},"ERR_REQUIRE_ASYNC_MODULE",".",[59,60,62],"h2",{"id":61},"a-module","A module",[64,65,70],"pre",{"className":66,"code":67,"language":68,"meta":69,"style":69},"language-javascript shiki shiki-themes github-light github-dark","exports.__esModule = true;\nexports.getLinks = getLinks;\nexports.myMouseWheel = mouseWheel;\n\ngetLinks.rfdoc = `Returns every link on the page as a name-to-href mapping.\n\nImplemented in JavaScript.`;\nasync function getLinks(logger, page) {\n  logger('Collecting links');\n  return await page.locator('a').evaluateAll(elements => {\n    const object = {};\n    elements.filter(e => e.innerText).forEach(e => (object[e.innerText] = e.href));\n    return object;\n  });\n}\n\nmouseWheel.rfdoc = 'Scrolls the page by mouse input.';\nasync function mouseWheel(x, y, logger, page) {\n  logger(`Mouse wheel at ${x}, ${y}`);\n  await page.mouse.wheel(Number(x), Number(y));\n  return await page.evaluate('document.scrollingElement.scrollTop');\n}\n","javascript","",[28,71,72,95,108,121,128,140,145,153,181,195,232,247,283,292,298,304,309,322,352,374,399,418],{"__ignoreMap":69},[73,74,77,81,85,89,92],"span",{"class":75,"line":76},"line",1,[73,78,80],{"class":79},"sj4cs","exports",[73,82,84],{"class":83},"sVt8B",".__esModule ",[73,86,88],{"class":87},"szBVR","=",[73,90,91],{"class":79}," true",[73,93,94],{"class":83},";\n",[73,96,98,100,103,105],{"class":75,"line":97},2,[73,99,80],{"class":79},[73,101,102],{"class":83},".getLinks ",[73,104,88],{"class":87},[73,106,107],{"class":83}," getLinks;\n",[73,109,111,113,116,118],{"class":75,"line":110},3,[73,112,80],{"class":79},[73,114,115],{"class":83},".myMouseWheel ",[73,117,88],{"class":87},[73,119,120],{"class":83}," mouseWheel;\n",[73,122,124],{"class":75,"line":123},4,[73,125,127],{"emptyLinePlaceholder":126},true,"\n",[73,129,131,134,136],{"class":75,"line":130},5,[73,132,133],{"class":83},"getLinks.rfdoc ",[73,135,88],{"class":87},[73,137,139],{"class":138},"sZZnC"," `Returns every link on the page as a name-to-href mapping.\n",[73,141,143],{"class":75,"line":142},6,[73,144,127],{"emptyLinePlaceholder":126},[73,146,148,151],{"class":75,"line":147},7,[73,149,150],{"class":138},"Implemented in JavaScript.`",[73,152,94],{"class":83},[73,154,156,159,162,166,169,173,176,178],{"class":75,"line":155},8,[73,157,158],{"class":87},"async",[73,160,161],{"class":87}," function",[73,163,165],{"class":164},"sScJk"," getLinks",[73,167,168],{"class":83},"(",[73,170,172],{"class":171},"s4XuR","logger",[73,174,175],{"class":83},", ",[73,177,30],{"class":171},[73,179,180],{"class":83},") {\n",[73,182,184,187,189,192],{"class":75,"line":183},9,[73,185,186],{"class":164},"  logger",[73,188,168],{"class":83},[73,190,191],{"class":138},"'Collecting links'",[73,193,194],{"class":83},");\n",[73,196,198,201,204,207,210,212,215,218,221,223,226,229],{"class":75,"line":197},10,[73,199,200],{"class":87},"  return",[73,202,203],{"class":87}," await",[73,205,206],{"class":83}," page.",[73,208,209],{"class":164},"locator",[73,211,168],{"class":83},[73,213,214],{"class":138},"'a'",[73,216,217],{"class":83},").",[73,219,220],{"class":164},"evaluateAll",[73,222,168],{"class":83},[73,224,225],{"class":171},"elements",[73,227,228],{"class":87}," =>",[73,230,231],{"class":83}," {\n",[73,233,235,238,241,244],{"class":75,"line":234},11,[73,236,237],{"class":87},"    const",[73,239,240],{"class":79}," object",[73,242,243],{"class":87}," =",[73,245,246],{"class":83}," {};\n",[73,248,250,253,256,258,261,263,266,269,271,273,275,278,280],{"class":75,"line":249},12,[73,251,252],{"class":83},"    elements.",[73,254,255],{"class":164},"filter",[73,257,168],{"class":83},[73,259,260],{"class":171},"e",[73,262,228],{"class":87},[73,264,265],{"class":83}," e.innerText).",[73,267,268],{"class":164},"forEach",[73,270,168],{"class":83},[73,272,260],{"class":171},[73,274,228],{"class":87},[73,276,277],{"class":83}," (object[e.innerText] ",[73,279,88],{"class":87},[73,281,282],{"class":83}," e.href));\n",[73,284,286,289],{"class":75,"line":285},13,[73,287,288],{"class":87},"    return",[73,290,291],{"class":83}," object;\n",[73,293,295],{"class":75,"line":294},14,[73,296,297],{"class":83},"  });\n",[73,299,301],{"class":75,"line":300},15,[73,302,303],{"class":83},"}\n",[73,305,307],{"class":75,"line":306},16,[73,308,127],{"emptyLinePlaceholder":126},[73,310,312,315,317,320],{"class":75,"line":311},17,[73,313,314],{"class":83},"mouseWheel.rfdoc ",[73,316,88],{"class":87},[73,318,319],{"class":138}," 'Scrolls the page by mouse input.'",[73,321,94],{"class":83},[73,323,325,327,329,332,334,337,339,342,344,346,348,350],{"class":75,"line":324},18,[73,326,158],{"class":87},[73,328,161],{"class":87},[73,330,331],{"class":164}," mouseWheel",[73,333,168],{"class":83},[73,335,336],{"class":171},"x",[73,338,175],{"class":83},[73,340,341],{"class":171},"y",[73,343,175],{"class":83},[73,345,172],{"class":171},[73,347,175],{"class":83},[73,349,30],{"class":171},[73,351,180],{"class":83},[73,353,355,357,359,362,364,367,369,372],{"class":75,"line":354},19,[73,356,186],{"class":164},[73,358,168],{"class":83},[73,360,361],{"class":138},"`Mouse wheel at ${",[73,363,336],{"class":83},[73,365,366],{"class":138},"}, ${",[73,368,341],{"class":83},[73,370,371],{"class":138},"}`",[73,373,194],{"class":83},[73,375,377,380,383,386,388,391,394,396],{"class":75,"line":376},20,[73,378,379],{"class":87},"  await",[73,381,382],{"class":83}," page.mouse.",[73,384,385],{"class":164},"wheel",[73,387,168],{"class":83},[73,389,390],{"class":164},"Number",[73,392,393],{"class":83},"(x), ",[73,395,390],{"class":164},[73,397,398],{"class":83},"(y));\n",[73,400,402,404,406,408,411,413,416],{"class":75,"line":401},21,[73,403,200],{"class":87},[73,405,203],{"class":87},[73,407,206],{"class":83},[73,409,410],{"class":164},"evaluate",[73,412,168],{"class":83},[73,414,415],{"class":138},"'document.scrollingElement.scrollTop'",[73,417,194],{"class":83},[73,419,421],{"class":75,"line":420},22,[73,422,303],{"class":83},[24,424,425],{},"Three conventions carry the whole API:",[427,428,429,457,463],"ul",{},[430,431,432,436,437,441,442,445,446,449,450,453,454,57],"li",{},[433,434,435],"strong",{},"Exported names become keywords"," — the ",[438,439,440],"em",{},"export key",", not the function's own\nname. ",[28,443,444],{},"exports.getLinks = getLinks"," gives ",[28,447,448],{},"Get Links","; the\n",[28,451,452],{},"exports.myMouseWheel = mouseWheel"," below gives ",[28,455,456],{},"My Mouse Wheel",[430,458,459,462],{},[433,460,461],{},"Five argument names are filled in for you",", by name — see below.",[430,464,465,471],{},[433,466,467,470],{},[28,468,469],{},"fn.rfdoc"," becomes the keyword documentation",", so your keyword shows up in\nLibdoc and in editor tooltips like any other.",[473,474,476],"h3",{"id":475},"the-five-names-browser-fills-in","The five names Browser fills in",[24,478,479],{},"Name a parameter one of these and the library passes the object in. Everything\nelse in your signature becomes an ordinary keyword argument.",[481,482,483,496],"table",{},[484,485,486],"thead",{},[487,488,489,493],"tr",{},[490,491,492],"th",{},"Name",[490,494,495],{},"You get",[497,498,499,516,530,544,553],"tbody",{},[487,500,501,506],{},[502,503,504],"td",{},[28,505,30],{},[502,507,508,509],{},"The active ",[510,511,515],"a",{"href":512,"rel":513},"https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fapi\u002Fclass-page",[514],"nofollow","Page",[487,517,518,523],{},[502,519,520],{},[28,521,522],{},"context",[502,524,508,525],{},[510,526,529],{"href":527,"rel":528},"https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fapi\u002Fclass-browsercontext",[514],"BrowserContext",[487,531,532,537],{},[502,533,534],{},[28,535,536],{},"browser",[502,538,508,539],{},[510,540,543],{"href":541,"rel":542},"https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fapi\u002Fclass-browser",[514],"Browser",[487,545,546,550],{},[502,547,548],{},[28,549,172],{},[502,551,552],{},"A function that writes to the Robot Framework log",[487,554,555,560],{},[502,556,557],{},[28,558,559],{},"playwright",[502,561,562,563,570],{},"The ",[510,564,567,569],{"href":565,"rel":566},"https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fapi\u002Fclass-playwright",[514],[28,568,559],{}," module"," itself",[24,572,573,576,577,580,581,584,585,587,588,590],{},[433,574,575],{},"They are matched by name, not by position."," Browser reads your parameter\nnames and fills in the ones it recognises, so ",[28,578,579],{},"mouseWheel(x, y, logger, page)","\nand ",[28,582,583],{},"mouseWheel(logger, x, page, y)"," behave identically — and the Robot side\nsees the same keyword either way, taking ",[28,586,336],{}," and ",[28,589,341],{},". Put them wherever reads\nbest.",[24,592,593,594,596,597,600],{},"These names are reserved: a keyword cannot take an argument called ",[28,595,30],{}," from\nRobot Framework, because that name is spoken for. ",[28,598,599],{},"self"," is not usable either.",[24,602,603,604,607,608,611,612,615],{},"One further name is special without being filled in. A parameter called ",[28,605,606],{},"args","\nmakes the keyword variadic — it receives Robot Framework's ",[28,609,610],{},"*args",", so it\ncarries values ",[438,613,614],{},"to"," your function rather than from the library. It cannot have a\ndefault, and anything you declare after it becomes a named-only argument on the\nRobot side, so it reads best last.",[24,617,618,619,622,623,57],{},"Whatever you return is JSON-serialised on the way back, so it must be\nserialisable — ",[28,620,621],{},"undefined"," arrives in Robot Framework as ",[28,624,625],{},"${None}",[24,627,628,631],{},[28,629,630],{},"jsextension"," takes a single path, a comma-separated list, or a real list of\npaths. Load it at import:",[64,633,637],{"className":634,"code":635,"language":636,"meta":69,"style":69},"language-robot shiki shiki-themes github-light github-dark","*** Settings ***\nLibrary    Browser    jsextension=${CURDIR}\u002Fmodule.js\n\n*** Test Cases ***\nRead The Links\n    New Page    https:\u002F\u002Fplaywright.dev\n    ${links} =    Get Links\n    Log Many    &{links}\n","robot",[28,638,639,644,649,653,658,663,668,673],{"__ignoreMap":69},[73,640,641],{"class":75,"line":76},[73,642,643],{},"*** Settings ***\n",[73,645,646],{"class":75,"line":97},[73,647,648],{},"Library    Browser    jsextension=${CURDIR}\u002Fmodule.js\n",[73,650,651],{"class":75,"line":110},[73,652,127],{"emptyLinePlaceholder":126},[73,654,655],{"class":75,"line":123},[73,656,657],{},"*** Test Cases ***\n",[73,659,660],{"class":75,"line":130},[73,661,662],{},"Read The Links\n",[73,664,665],{"class":75,"line":142},[73,666,667],{},"    New Page    https:\u002F\u002Fplaywright.dev\n",[73,669,670],{"class":75,"line":147},[73,671,672],{},"    ${links} =    Get Links\n",[73,674,675],{"class":75,"line":155},[73,676,677],{},"    Log Many    &{links}\n",[59,679,681],{"id":680},"custom-selector-strategies","Custom selector strategies",[24,683,684],{},"A module can also register a selector engine, which then works anywhere a\nselector is accepted:",[64,686,688],{"className":66,"code":687,"language":68,"meta":69,"style":69},"async function registerMySelector(playwright) {\n  await playwright.selectors.register('myselector', () => ({\n    query(root, selector) {\n      return root.querySelector(`a[data-title=\"${selector}\"]`);\n    },\n    queryAll(root, selector) {\n      return Array.from(root.querySelectorAll(`a[data-title=\"${selector}\"]`));\n    },\n  }));\n}\nexports.__esModule = true;\nexports.registerMySelector = registerMySelector;\n",[28,689,690,705,729,746,769,774,789,816,820,825,829,841],{"__ignoreMap":69},[73,691,692,694,696,699,701,703],{"class":75,"line":76},[73,693,158],{"class":87},[73,695,161],{"class":87},[73,697,698],{"class":164}," registerMySelector",[73,700,168],{"class":83},[73,702,559],{"class":171},[73,704,180],{"class":83},[73,706,707,709,712,715,717,720,723,726],{"class":75,"line":97},[73,708,379],{"class":87},[73,710,711],{"class":83}," playwright.selectors.",[73,713,714],{"class":164},"register",[73,716,168],{"class":83},[73,718,719],{"class":138},"'myselector'",[73,721,722],{"class":83},", () ",[73,724,725],{"class":87},"=>",[73,727,728],{"class":83}," ({\n",[73,730,731,734,736,739,741,744],{"class":75,"line":110},[73,732,733],{"class":164},"    query",[73,735,168],{"class":83},[73,737,738],{"class":171},"root",[73,740,175],{"class":83},[73,742,743],{"class":171},"selector",[73,745,180],{"class":83},[73,747,748,751,754,757,759,762,764,767],{"class":75,"line":123},[73,749,750],{"class":87},"      return",[73,752,753],{"class":83}," root.",[73,755,756],{"class":164},"querySelector",[73,758,168],{"class":83},[73,760,761],{"class":138},"`a[data-title=\"${",[73,763,743],{"class":83},[73,765,766],{"class":138},"}\"]`",[73,768,194],{"class":83},[73,770,771],{"class":75,"line":130},[73,772,773],{"class":83},"    },\n",[73,775,776,779,781,783,785,787],{"class":75,"line":142},[73,777,778],{"class":164},"    queryAll",[73,780,168],{"class":83},[73,782,738],{"class":171},[73,784,175],{"class":83},[73,786,743],{"class":171},[73,788,180],{"class":83},[73,790,791,793,796,799,802,805,807,809,811,813],{"class":75,"line":147},[73,792,750],{"class":87},[73,794,795],{"class":83}," Array.",[73,797,798],{"class":164},"from",[73,800,801],{"class":83},"(root.",[73,803,804],{"class":164},"querySelectorAll",[73,806,168],{"class":83},[73,808,761],{"class":138},[73,810,743],{"class":83},[73,812,766],{"class":138},[73,814,815],{"class":83},"));\n",[73,817,818],{"class":75,"line":155},[73,819,773],{"class":83},[73,821,822],{"class":75,"line":183},[73,823,824],{"class":83},"  }));\n",[73,826,827],{"class":75,"line":197},[73,828,303],{"class":83},[73,830,831,833,835,837,839],{"class":75,"line":234},[73,832,80],{"class":79},[73,834,84],{"class":83},[73,836,88],{"class":87},[73,838,91],{"class":79},[73,840,94],{"class":83},[73,842,843,845,848,850],{"class":75,"line":249},[73,844,80],{"class":79},[73,846,847],{"class":83},".registerMySelector ",[73,849,88],{"class":87},[73,851,852],{"class":83}," registerMySelector;\n",[64,854,856],{"className":634,"code":855,"language":636,"meta":69,"style":69},"*** Test Cases ***\nUse A Custom Engine\n    New Browser           chromium\n    Register My Selector      # a browser must already be open\n    New Page              ${URL}\n    Click                 myselector=Some Title\n",[28,857,858,862,867,872,877,882],{"__ignoreMap":69},[73,859,860],{"class":75,"line":76},[73,861,657],{},[73,863,864],{"class":75,"line":97},[73,865,866],{},"Use A Custom Engine\n",[73,868,869],{"class":75,"line":110},[73,870,871],{},"    New Browser           chromium\n",[73,873,874],{"class":75,"line":123},[73,875,876],{},"    Register My Selector      # a browser must already be open\n",[73,878,879],{"class":75,"line":130},[73,880,881],{},"    New Page              ${URL}\n",[73,883,884],{"class":75,"line":142},[73,885,886],{},"    Click                 myselector=Some Title\n",[888,889,891,894,906],"doc-note",{"kind":890},"warning",[24,892,893],{},"Two things this example depends on.",[24,895,896,899,900,902,903],{},[433,897,898],{},"A browser must already be open."," Every JavaScript-extension keyword resolves\nthe active browser before it runs, even one whose only argument is ",[28,901,559],{},",\nso calling this first fails with ",[28,904,905],{},"Browser has been closed.",[24,907,908,911,912,915],{},[433,909,910],{},"Register once per run."," ",[28,913,914],{},"selectors.register"," rejects a name that is already\nregistered, and because the registration is awaited that rejection fails the\nkeyword — unawaited, it takes the whole Node process down instead.",[59,917,919],{"id":918},"debugging","Debugging",[24,921,922],{},"You can attach a Node debugger to the Playwright process — to your own extension\nor to the library's internals.",[473,924,926],{"id":925},"_1-start-node-with-debugging-enabled","1. Start Node with debugging enabled",[24,928,929,930,933],{},"Set ",[28,931,932],{},"ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS","; its value is passed to the\nNode process as CLI options.",[935,936],"doc-table",{":head":937,":rows":938},"[\"Option\",\"Behaviour\"]","[[\"`--inspect`\",\"Debugging on, process starts immediately. Attach whenever.\"],[\"`--inspect-brk`\",\"Process pauses until a debugger attaches. Needed to debug startup.\"]]",[24,940,941],{},"Bind it to a specific port so it does not collide with anything else:",[64,943,948],{"className":944,"code":946,"language":947},[945],"language-text","--inspect=127.0.0.1:9999\n","text",[28,949,946],{"__ignoreMap":69},[24,951,952,953,956],{},"Set it for the debug session rather than globally. For RobotCode, in\n",[28,954,955],{},"launch.json",":",[64,958,962],{"className":959,"code":960,"language":961,"meta":69,"style":69},"language-json shiki shiki-themes github-light github-dark","{\n  \"name\": \"RobotCode: Default\",\n  \"type\": \"robotcode\",\n  \"request\": \"launch\",\n  \"purpose\": \"default\",\n  \"env\": {\n    \"ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS\": \"--inspect=127.0.0.1:9999\"\n  },\n  \"pythonConfiguration\": \"RobotCode: Python\"\n}\n","json",[28,963,964,969,983,995,1007,1019,1027,1037,1042,1052],{"__ignoreMap":69},[73,965,966],{"class":75,"line":76},[73,967,968],{"class":83},"{\n",[73,970,971,974,977,980],{"class":75,"line":97},[73,972,973],{"class":79},"  \"name\"",[73,975,976],{"class":83},": ",[73,978,979],{"class":138},"\"RobotCode: Default\"",[73,981,982],{"class":83},",\n",[73,984,985,988,990,993],{"class":75,"line":110},[73,986,987],{"class":79},"  \"type\"",[73,989,976],{"class":83},[73,991,992],{"class":138},"\"robotcode\"",[73,994,982],{"class":83},[73,996,997,1000,1002,1005],{"class":75,"line":123},[73,998,999],{"class":79},"  \"request\"",[73,1001,976],{"class":83},[73,1003,1004],{"class":138},"\"launch\"",[73,1006,982],{"class":83},[73,1008,1009,1012,1014,1017],{"class":75,"line":130},[73,1010,1011],{"class":79},"  \"purpose\"",[73,1013,976],{"class":83},[73,1015,1016],{"class":138},"\"default\"",[73,1018,982],{"class":83},[73,1020,1021,1024],{"class":75,"line":142},[73,1022,1023],{"class":79},"  \"env\"",[73,1025,1026],{"class":83},": {\n",[73,1028,1029,1032,1034],{"class":75,"line":147},[73,1030,1031],{"class":79},"    \"ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS\"",[73,1033,976],{"class":83},[73,1035,1036],{"class":138},"\"--inspect=127.0.0.1:9999\"\n",[73,1038,1039],{"class":75,"line":155},[73,1040,1041],{"class":83},"  },\n",[73,1043,1044,1047,1049],{"class":75,"line":183},[73,1045,1046],{"class":79},"  \"pythonConfiguration\"",[73,1048,976],{"class":83},[73,1050,1051],{"class":138},"\"RobotCode: Python\"\n",[73,1053,1054],{"class":75,"line":197},[73,1055,303],{"class":83},[888,1057,1058],{"kind":890},[24,1059,1060,1061,1064,1065,1068],{},"With ",[28,1062,1063],{},"--inspect-brk"," you have to attach quickly: the Playwright process start\nhas a timeout of about ",[433,1066,1067],{},"15 seconds",". Miss it and the run fails before you are\nattached. On macOS a failed start is retried once, but the first process is\nkilled and a second one started, so you still only get those 15 seconds to\nattach to any one process.",[473,1070,1072],{"id":1071},"_2-attach","2. Attach",[64,1074,1076],{"className":959,"code":1075,"language":961,"meta":69,"style":69},"{\n  \"name\": \"Attach to Node\",\n  \"port\": 9999,\n  \"type\": \"node\",\n  \"request\": \"attach\",\n  \"skipFiles\": [\"\u003Cnode_internals>\u002F**\"]\n}\n",[28,1077,1078,1082,1093,1105,1116,1127,1141],{"__ignoreMap":69},[73,1079,1080],{"class":75,"line":76},[73,1081,968],{"class":83},[73,1083,1084,1086,1088,1091],{"class":75,"line":97},[73,1085,973],{"class":79},[73,1087,976],{"class":83},[73,1089,1090],{"class":138},"\"Attach to Node\"",[73,1092,982],{"class":83},[73,1094,1095,1098,1100,1103],{"class":75,"line":110},[73,1096,1097],{"class":79},"  \"port\"",[73,1099,976],{"class":83},[73,1101,1102],{"class":79},"9999",[73,1104,982],{"class":83},[73,1106,1107,1109,1111,1114],{"class":75,"line":123},[73,1108,987],{"class":79},[73,1110,976],{"class":83},[73,1112,1113],{"class":138},"\"node\"",[73,1115,982],{"class":83},[73,1117,1118,1120,1122,1125],{"class":75,"line":130},[73,1119,999],{"class":79},[73,1121,976],{"class":83},[73,1123,1124],{"class":138},"\"attach\"",[73,1126,982],{"class":83},[73,1128,1129,1132,1135,1138],{"class":75,"line":142},[73,1130,1131],{"class":79},"  \"skipFiles\"",[73,1133,1134],{"class":83},": [",[73,1136,1137],{"class":138},"\"\u003Cnode_internals>\u002F**\"",[73,1139,1140],{"class":83},"]\n",[73,1142,1143],{"class":75,"line":147},[73,1144,303],{"class":83},[473,1146,1148],{"id":1147},"_3-run","3. Run",[1150,1151,1152,1159,1170,1173],"ol",{},[430,1153,1154,1155,1158],{},"Set breakpoints in your extension — or in\n",[28,1156,1157],{},"site-packages\u002FBrowser\u002Fwrapper\u002Findex.js"," to debug the library itself.",[430,1160,1161,1162,1165,1166,1169],{},"Set a breakpoint in the Robot code ",[433,1163,1164],{},"early",", after ",[28,1167,1168],{},"Library Browser"," is\nloaded and before your JS runs. This buys you the time to attach.",[430,1171,1172],{},"Start the Robot debug session and wait for that breakpoint.",[430,1174,1175,1176,1179,1180,1183],{},"Switch to ",[438,1177,1178],{},"Run and Debug",", choose ",[438,1181,1182],{},"Attach to Node",", and start it.",[24,1185,1186],{},"Step 2 is the one people skip, and then wonder why the JS breakpoint never\nfires: without it the extension has already run by the time you attach.",[59,1188,1190],{"id":1189},"which-extension-point","Which extension point?",[935,1192],{":head":1193,":rows":1194},"[\"You want\",\"Use\"]","[[\"Playwright APIs Browser does not expose\",\"JavaScript module\"],[\"Assertion arguments like the built-in getters\",\"Python plugin with AssertionEngine\"],[\"To replace an existing keyword\",\"Python plugin\"],[\"A custom selector engine\",\"JavaScript module\"],[\"Both Python and page-side logic in one keyword\",\"Python plugin calling a JS module\"]]",[59,1196,1198],{"id":1197},"before-you-write-one","Before you write one",[24,1200,1201,1202,1207],{},"Somebody may have already written it.\n",[510,1203,1206],{"href":1204,"rel":1205},"https:\u002F\u002Fgithub.com\u002FMarketSquare\u002Frobotframework-browser-extensions",[514],"robotframework-browser-extensions","\ncollects working community extensions — accessibility checks with axe-core,\nvisual comparison, network throttling, request mocking, element highlighting,\nand native Playwright page methods.",[24,1209,1210],{},"Reading one is also the fastest way to see the shape of a finished extension\nrather than a snippet. And when yours works, it belongs there too: it is a\nmonorepo that takes pull requests, so publishing is one PR rather than a\nrelease process.",[1212,1213,1214],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":69,"searchDepth":97,"depth":97,"links":1216},[1217,1220,1221,1226,1227],{"id":61,"depth":97,"text":62,"children":1218},[1219],{"id":475,"depth":110,"text":476},{"id":680,"depth":97,"text":681},{"id":918,"depth":97,"text":919,"children":1222},[1223,1224,1225],{"id":925,"depth":110,"text":926},{"id":1071,"depth":110,"text":1072},{"id":1147,"depth":110,"text":1148},{"id":1189,"depth":97,"text":1190},{"id":1197,"depth":97,"text":1198},"Add keywords that run on the Node side with full Playwright access — and attach a debugger to them.","md",{},"\u002Fdocs\u002Fextending\u002Fjavascript-extensions","extending",{"title":19,"description":1228},"docs\u002Fextending\u002Fjavascript-extensions","Ft88UKwAYpojTelaPrqP_SmQmoI2PA_v7PCGvIlFrMU",[1237,1242,1246,1250,1254,1258,1262,1266,1267,1271,1275,1280,1284,1288,1293,1297,1301,1305],{"path":1238,"title":1239,"description":1240,"section":1241,"order":130},"\u002Fdocs\u002Fconcepts\u002Farchitecture","How Browser works","Python, a Node process and Playwright — what runs where, and which installation to choose.","concepts",{"path":1243,"title":1244,"description":1245,"section":1241,"order":110},"\u002Fdocs\u002Fconcepts\u002Fassertions","Assertions","Almost every getter can assert, every assertion retries, and each return type allows different operators. The complete AssertionEngine reference.",{"path":1247,"title":1248,"description":1249,"section":1241,"order":76},"\u002Fdocs\u002Fconcepts\u002Fbrowser-context-page","Browser, context and page","The three layers Playwright is built on — and why a new context is the cheapest clean slate you will ever get.",{"path":1251,"title":1252,"description":1253,"section":1241,"order":142},"\u002Fdocs\u002Fconcepts\u002Flogging","Logging and debugging","Four places Browser tells you what happened — log.html, the Playwright log, traces and coverage.",{"path":1255,"title":1256,"description":1257,"section":1241,"order":97},"\u002Fdocs\u002Fconcepts\u002Fselectors","Finding elements","Which selector strategy to reach for, why the order matters, and how to chain across iframes and shadow DOM.",{"path":1259,"title":1260,"description":1261,"section":1241,"order":123},"\u002Fdocs\u002Fconcepts\u002Fwaiting","Waiting and promises","Most waiting is already done for you. This is the rest of it — Wait For Condition, and how to run keywords in parallel with Promise To.",{"path":1263,"title":1264,"description":1265,"section":1232,"order":97},"\u002Fdocs\u002Fextending\u002Fjavascript-basics","Just enough JavaScript","The JavaScript you need to write extensions and Evaluate JavaScript, for people who write Python.",{"path":1231,"title":19,"description":1228,"section":1232,"order":110},{"path":1268,"title":1269,"description":1270,"section":1232,"order":76},"\u002Fdocs\u002Fextending\u002Fpython-plugins","Python plugins","Add or replace keywords from Python, with access to the library's own API and to the Node side.",{"path":1272,"title":1273,"description":1274,"section":1232,"order":123},"\u002Fdocs\u002Fextending\u002Ftranslations","Translating keywords","Using a translation package to get keyword names and documentation in your language, and writing one for a language nobody has covered yet.",{"path":1276,"title":1277,"description":1278,"section":1279,"order":97},"\u002Fdocs\u002Fmobile\u002Fdevices","Emulating a device","Device descriptors, what the six or seven properties they set actually change, and the one that emulation cannot give you.","mobile",{"path":1281,"title":1282,"description":1283,"section":1279,"order":76},"\u002Fdocs\u002Fmobile\u002Fresponsive","Testing responsive pages","Why a browser at a phone-sized viewport tests responsiveness properly, what emulation cannot tell you, and where real devices actually belong.",{"path":1285,"title":1286,"description":1287,"section":1279,"order":110},"\u002Fdocs\u002Fmobile\u002Ftouch","Touch, permissions and location","Tap and why it needs hasTouch, granting camera or notifications without a dialog, faking where the user is, and the gestures Browser has no keyword for.",{"path":1289,"title":1290,"description":1291,"section":1292,"order":110},"\u002Fdocs\u002Foperations\u002Fdocker","Running in Docker","The published Browser image, the four docker run flags that matter, and why running as root breaks Chromium.","operations",{"path":1294,"title":1295,"description":1296,"section":1292,"order":123},"\u002Fdocs\u002Foperations\u002Fdocker-images","Building your own image","Extending the published image with your dependencies, the version lock between Browser and Playwright, and using it as a CI job container.",{"path":1298,"title":1299,"description":1300,"section":1292,"order":97},"\u002Fdocs\u002Foperations\u002Fenvironment-variables","Environment variables","The variables that change how Browser behaves, which of them are safe in production, and the import parameters that should usually be preferred.",{"path":1302,"title":1303,"description":1304,"section":1292,"order":76},"\u002Fdocs\u002Foperations\u002Fnode-process","The Node process","Browser starts a Node process to talk to Playwright. What that costs, how to share one across parallel runs, and how to pass it Node flags.",{"path":1306,"title":1307,"description":1308,"section":1309,"order":76},"\u002Fdocs\u002Fstart\u002Fgetting-started","Getting started","Install Browser, write a first test, and run it.","start",[1311,1314,1317],{"to":1312,"label":1313},"\u002Fwhy\u002Fvs-cypress","vs Cypress",{"to":1315,"label":1316},"\u002Fwhy\u002Fvs-playwright","vs Playwright Test",{"to":1318,"label":1319},"\u002Fwhy\u002Fvs-seleniumlibrary","vs SeleniumLibrary",[1321],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">exports\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">__esModule\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> true\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">exports\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">getLinks\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> getLinks\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">exports\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">myMouseWheel\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> mouseWheel\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFB86B\">getLinks\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">rfdoc\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> `\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">Returns every link on the page as a name-to-href mapping.\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E0D3A3\">Implemented in JavaScript.\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">async\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> getLinks\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">logger\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">)\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">  logger\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">Collecting links\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">  return\u003C\u002Fspan>\u003Cspan style=\"color:#C9A6E9\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">locator\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">a\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">).\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">evaluateAll\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">elements \u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">=>\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    const\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> object\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {};\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFB86B\">    elements\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">filter\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">e \u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">=>\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> e\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">innerText\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">).\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">forEach\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">e \u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">=>\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">object\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">[\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">e\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">innerText\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">]\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> e\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">href\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">));\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> object\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  });\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FFB86B\">mouseWheel\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">rfdoc\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> '\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">Scrolls the page by mouse input.\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">async\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> mouseWheel\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">x\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> y\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> logger\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">)\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">  logger\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">Mouse wheel at \u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">x\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">y\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}`\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">  await\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">mouse\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">wheel\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">Number\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">x\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">),\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> Number\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">y\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">));\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">  return\u003C\u002Fspan>\u003Cspan style=\"color:#C9A6E9\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">evaluate\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">document.scrollingElement.scrollTop\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>",[1323],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF6B5E;font-weight:bold\">*** Settings ***\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">Library\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">    Browser\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">    jsextension=\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">CURDIR\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">\u002Fmodule.js\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF6B5E;font-weight:bold\">*** Test Cases ***\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">Read The Links\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    New Page\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">    https:\u002F\u002Fplaywright.dev\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">    ${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">links\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">    Get Links\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    Log Many\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">    &#x26;{\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">links\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>",[1325],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">async\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> function\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> registerMySelector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">playwright\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">)\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">  await\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> playwright\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">selectors\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">register\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">myselector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">'\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> ()\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\"> =>\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> ({\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    query\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">root\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> selector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">)\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">      return\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> root\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">querySelector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">a[data-title=\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">selector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">\"]\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">);\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">    },\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    queryAll\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\">root\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003Cspan style=\"color:#E2E1D7\"> selector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">)\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#C9A6E9\">      return\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> Array\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">from\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">root\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">querySelectorAll\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">(\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">a[data-title=\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">selector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">\"]\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">`\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">));\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">    },\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  }));\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">exports\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">__esModule\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> true\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">exports\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">.\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">registerMySelector\u003C\u002Fspan>\u003Cspan style=\"color:#FF6B5E\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> registerMySelector\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">;\u003C\u002Fspan>\u003C\u002Fspan>",[1327],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#FF6B5E;font-weight:bold\">*** Test Cases ***\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">Use A Custom Engine\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    New Browser\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">           chromium\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    Register My Selector\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">      # a browser must already be open\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    New Page\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">              ${\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\">URL\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#2BD9CC\">    Click\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">                 myselector=Some Title\u003C\u002Fspan>\u003C\u002Fspan>",[1329],"\u003Cspan class=\"line\">\u003Cspan>--inspect=127.0.0.1:9999\u003C\u002Fspan>\u003C\u002Fspan>",[1331],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">{\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">name\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">RobotCode: Default\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">type\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">robotcode\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">request\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">launch\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">purpose\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">default\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">env\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> {\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">    \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">ROBOT_FRAMEWORK_BROWSER_NODE_DEBUG_OPTIONS\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">--inspect=127.0.0.1:9999\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  },\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">pythonConfiguration\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">RobotCode: Python\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>",[1333],"\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">{\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">name\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">Attach to Node\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">port\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#FFB86B\"> 9999\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">type\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">node\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">request\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> \"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">attach\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">,\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">  \"\u003C\u002Fspan>\u003Cspan style=\"color:#2BD9CC\">skipFiles\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">:\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#E0D3A3\">&#x3C;node_internals>\u002F**\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#A9B4BA\">]\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan class=\"line\">\u003Cspan style=\"color:#A9B4BA\">}\u003C\u002Fspan>\u003C\u002Fspan>",1786734140327]