How to use waitForSelectorTask method in Playwright Internal

Best JavaScript code snippet using playwright-internal

frames.js

Source:frames.js Github

copy

Full Screen

...573 frame,574 info575 } = selectorInFrame;576 const actualScope = this === frame ? scope : undefined;577 const task = dom.waitForSelectorTask(info, state, options.omitReturnValue, actualScope);578 const result = actualScope ? await frame._runWaitForSelectorTaskOnce(progress, (0, _selectorParser.stringifySelector)(info.parsed), info.world, task) : await frame._scheduleRerunnableHandleTask(progress, info.world, task);579 if (!result.asElement()) {580 result.dispose();581 return null;582 }583 if (options.__testHookBeforeAdoptNode) await options.__testHookBeforeAdoptNode();584 const handle = result.asElement();585 try {586 return await handle._adoptTo(await frame._mainContext());587 } catch (e) {588 return continuePolling;589 }590 }, scope);591 }, this._page._timeoutSettings.timeout(options));592 }593 async dispatchEvent(metadata, selector, type, eventInit = {}, options = {}) {594 await this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => {595 progress.injectedScript.dispatchEvent(element, data.type, data.eventInit);596 }, {597 type,598 eventInit599 }, {600 mainWorld: true,601 ...options602 });603 await this._page._doSlowMo();604 }605 async evalOnSelectorAndWaitForSignals(selector, strict, expression, isFunction, arg) {606 const pair = await this.resolveFrameForSelectorNoWait(selector, {607 strict608 });609 const handle = pair ? await this._page.selectors.query(pair.frame, pair.info) : null;610 if (!handle) throw new Error(`Error: failed to find element matching selector "${selector}"`);611 const result = await handle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);612 handle.dispose();613 return result;614 }615 async evalOnSelectorAllAndWaitForSignals(selector, expression, isFunction, arg) {616 const pair = await this.resolveFrameForSelectorNoWait(selector, {});617 if (!pair) throw new Error(`Error: failed to find frame for selector "${selector}"`);618 const arrayHandle = await this._page.selectors._queryArrayInMainWorld(pair.frame, pair.info);619 const result = await arrayHandle.evaluateExpressionAndWaitForSignals(expression, isFunction, true, arg);620 arrayHandle.dispose();621 return result;622 }623 async querySelectorAll(selector) {624 const pair = await this.resolveFrameForSelectorNoWait(selector, {});625 if (!pair) return [];626 return this._page.selectors._queryAll(pair.frame, pair.info, undefined, true627 /* adoptToMain */628 );629 }630 async queryCount(selector) {631 const pair = await this.resolveFrameForSelectorNoWait(selector);632 if (!pair) throw new Error(`Error: failed to find frame for selector "${selector}"`);633 return await this._page.selectors._queryCount(pair.frame, pair.info);634 }635 async content() {636 try {637 const context = await this._utilityContext();638 return await context.evaluate(() => {639 let retVal = '';640 if (document.doctype) retVal = new XMLSerializer().serializeToString(document.doctype);641 if (document.documentElement) retVal += document.documentElement.outerHTML;642 return retVal;643 });644 } catch (e) {645 if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) throw e;646 throw new Error(`Unable to retrieve content because the page is navigating and changing the content.`);647 }648 }649 async setContent(metadata, html, options = {}) {650 const controller = new _progress.ProgressController(metadata, this);651 return controller.run(progress => this.raceNavigationAction(async () => {652 const waitUntil = options.waitUntil === undefined ? 'load' : options.waitUntil;653 progress.log(`setting frame content, waiting until "${waitUntil}"`);654 const tag = `--playwright--set--content--${this._id}--${++this._setContentCounter}--`;655 const context = await this._utilityContext();656 const lifecyclePromise = new Promise((resolve, reject) => {657 this._page._frameManager._consoleMessageTags.set(tag, () => {658 // Clear lifecycle right after document.open() - see 'tag' below.659 this._onClearLifecycle();660 this._waitForLoadState(progress, waitUntil).then(resolve).catch(reject);661 });662 });663 const contentPromise = context.evaluate(({664 html,665 tag666 }) => {667 window.stop();668 document.open();669 console.debug(tag); // eslint-disable-line no-console670 document.write(html);671 document.close();672 }, {673 html,674 tag675 });676 await Promise.all([contentPromise, lifecyclePromise]);677 await this._page._doSlowMo();678 }), this._page._timeoutSettings.navigationTimeout(options));679 }680 name() {681 return this._name || '';682 }683 url() {684 return this._url;685 }686 parentFrame() {687 return this._parentFrame;688 }689 childFrames() {690 return Array.from(this._childFrames);691 }692 async addScriptTag(params) {693 const {694 url = null,695 content = null,696 type = ''697 } = params;698 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');699 const context = await this._mainContext();700 return this._raceWithCSPError(async () => {701 if (url !== null) return (await context.evaluateHandle(addScriptUrl, {702 url,703 type704 })).asElement();705 const result = (await context.evaluateHandle(addScriptContent, {706 content: content,707 type708 })).asElement(); // Another round trip to the browser to ensure that we receive CSP error messages709 // (if any) logged asynchronously in a separate task on the content main thread.710 if (this._page._delegate.cspErrorsAsynchronousForInlineScipts) await context.evaluate(() => true);711 return result;712 });713 async function addScriptUrl(params) {714 const script = document.createElement('script');715 script.src = params.url;716 if (params.type) script.type = params.type;717 const promise = new Promise((res, rej) => {718 script.onload = res;719 script.onerror = e => rej(typeof e === 'string' ? new Error(e) : new Error(`Failed to load script at ${script.src}`));720 });721 document.head.appendChild(script);722 await promise;723 return script;724 }725 function addScriptContent(params) {726 const script = document.createElement('script');727 script.type = params.type || 'text/javascript';728 script.text = params.content;729 let error = null;730 script.onerror = e => error = e;731 document.head.appendChild(script);732 if (error) throw error;733 return script;734 }735 }736 async addStyleTag(params) {737 const {738 url = null,739 content = null740 } = params;741 if (!url && !content) throw new Error('Provide an object with a `url`, `path` or `content` property');742 const context = await this._mainContext();743 return this._raceWithCSPError(async () => {744 if (url !== null) return (await context.evaluateHandle(addStyleUrl, url)).asElement();745 return (await context.evaluateHandle(addStyleContent, content)).asElement();746 });747 async function addStyleUrl(url) {748 const link = document.createElement('link');749 link.rel = 'stylesheet';750 link.href = url;751 const promise = new Promise((res, rej) => {752 link.onload = res;753 link.onerror = rej;754 });755 document.head.appendChild(link);756 await promise;757 return link;758 }759 async function addStyleContent(content) {760 const style = document.createElement('style');761 style.type = 'text/css';762 style.appendChild(document.createTextNode(content));763 const promise = new Promise((res, rej) => {764 style.onload = res;765 style.onerror = rej;766 });767 document.head.appendChild(style);768 await promise;769 return style;770 }771 }772 async _raceWithCSPError(func) {773 const listeners = [];774 let result;775 let error;776 let cspMessage;777 const actionPromise = func().then(r => result = r).catch(e => error = e);778 const errorPromise = new Promise(resolve => {779 listeners.push(_eventsHelper.eventsHelper.addEventListener(this._page, _page.Page.Events.Console, message => {780 if (message.type() === 'error' && message.text().includes('Content Security Policy')) {781 cspMessage = message;782 resolve();783 }784 }));785 });786 await Promise.race([actionPromise, errorPromise]);787 _eventsHelper.eventsHelper.removeEventListeners(listeners);788 if (cspMessage) throw new Error(cspMessage.text());789 if (error) throw error;790 return result;791 }792 async retryWithProgress(progress, selector, options, action, scope) {793 const continuePolling = Symbol('continuePolling');794 while (progress.isRunning()) {795 let selectorInFrame;796 if (options.omitAttached) {797 selectorInFrame = await this.resolveFrameForSelectorNoWait(selector, options, scope);798 } else {799 selectorInFrame = await this._resolveFrameForSelector(progress, selector, options, scope);800 if (!selectorInFrame) {801 // Missing content frame.802 await new Promise(f => setTimeout(f, 100));803 continue;804 }805 }806 try {807 const result = await action(selectorInFrame, continuePolling);808 if (result === continuePolling) continue;809 return result;810 } catch (e) {811 var _selectorInFrame;812 // Always fail on JavaScript errors or when the main connection is closed.813 if (js.isJavaScriptErrorInEvaluate(e) || (0, _protocolError.isSessionClosedError)(e)) throw e; // Certain error opt-out of the retries, throw.814 if (dom.isNonRecoverableDOMError(e)) throw e; // If the call is made on the detached frame - throw.815 if (this.isDetached()) throw e; // If there is scope, and scope is within the frame we use to select, assume context is destroyed and816 // operation is not recoverable.817 if (scope && scope._context.frame === ((_selectorInFrame = selectorInFrame) === null || _selectorInFrame === void 0 ? void 0 : _selectorInFrame.frame)) throw e; // Retry upon all other errors.818 continue;819 }820 }821 progress.throwIfAborted();822 return undefined;823 }824 async _retryWithProgressIfNotConnected(progress, selector, strict, action) {825 return this.retryWithProgress(progress, selector, {826 strict827 }, async (selectorInFrame, continuePolling) => {828 // We did not pass omitAttached, so selectorInFrame is not null.829 const {830 frame,831 info832 } = selectorInFrame; // Be careful, |this| can be different from |frame|.833 const task = dom.waitForSelectorTask(info, 'attached');834 progress.log(`waiting for selector "${selector}"`);835 const handle = await frame._scheduleRerunnableHandleTask(progress, info.world, task);836 const element = handle.asElement();837 try {838 const result = await action(element);839 if (result === 'error:notconnected') {840 progress.log('element was detached from the DOM, retrying');841 return continuePolling;842 }843 return result;844 } finally {845 element === null || element === void 0 ? void 0 : element.dispose();846 }847 });848 }849 async click(metadata, selector, options) {850 const controller = new _progress.ProgressController(metadata, this);851 return controller.run(async progress => {852 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._click(progress, options)));853 }, this._page._timeoutSettings.timeout(options));854 }855 async dblclick(metadata, selector, options = {}) {856 const controller = new _progress.ProgressController(metadata, this);857 return controller.run(async progress => {858 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._dblclick(progress, options)));859 }, this._page._timeoutSettings.timeout(options));860 }861 async dragAndDrop(metadata, source, target, options = {}) {862 const controller = new _progress.ProgressController(metadata, this);863 await controller.run(async progress => {864 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, async handle => {865 return handle._retryPointerAction(progress, 'move and down', false, async point => {866 await this._page.mouse.move(point.x, point.y);867 await this._page.mouse.down();868 }, { ...options,869 position: options.sourcePosition,870 timeout: progress.timeUntilDeadline()871 });872 }));873 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, async handle => {874 return handle._retryPointerAction(progress, 'move and up', false, async point => {875 await this._page.mouse.move(point.x, point.y);876 await this._page.mouse.up();877 }, { ...options,878 position: options.targetPosition,879 timeout: progress.timeUntilDeadline()880 });881 }));882 }, this._page._timeoutSettings.timeout(options));883 }884 async tap(metadata, selector, options) {885 const controller = new _progress.ProgressController(metadata, this);886 return controller.run(async progress => {887 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._tap(progress, options)));888 }, this._page._timeoutSettings.timeout(options));889 }890 async fill(metadata, selector, value, options) {891 const controller = new _progress.ProgressController(metadata, this);892 return controller.run(async progress => {893 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._fill(progress, value, options)));894 }, this._page._timeoutSettings.timeout(options));895 }896 async focus(metadata, selector, options = {}) {897 const controller = new _progress.ProgressController(metadata, this);898 await controller.run(async progress => {899 dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._focus(progress)));900 await this._page._doSlowMo();901 }, this._page._timeoutSettings.timeout(options));902 }903 async textContent(metadata, selector, options = {}) {904 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.textContent, undefined, options);905 }906 async innerText(metadata, selector, options = {}) {907 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => {908 if (element.namespaceURI !== 'http://www.w3.org/1999/xhtml') throw progress.injectedScript.createStacklessError('Node is not an HTMLElement');909 return element.innerText;910 }, undefined, options);911 }912 async innerHTML(metadata, selector, options = {}) {913 return this._scheduleRerunnableTask(metadata, selector, (progress, element) => element.innerHTML, undefined, options);914 }915 async getAttribute(metadata, selector, name, options = {}) {916 return this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => element.getAttribute(data.name), {917 name918 }, options);919 }920 async inputValue(metadata, selector, options = {}) {921 return this._scheduleRerunnableTask(metadata, selector, (progress, node) => {922 const element = progress.injectedScript.retarget(node, 'follow-label');923 if (!element || element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA' && element.nodeName !== 'SELECT') throw progress.injectedScript.createStacklessError('Node is not an <input>, <textarea> or <select> element');924 return element.value;925 }, undefined, options);926 }927 async highlight(selector) {928 const pair = await this.resolveFrameForSelectorNoWait(selector);929 if (!pair) return;930 const context = await this._utilityContext();931 const injectedScript = await context.injectedScript();932 return await injectedScript.evaluate((injected, {933 parsed934 }) => {935 return injected.highlight(parsed);936 }, {937 parsed: pair.info.parsed938 });939 }940 async hideHighlight() {941 const context = await this._utilityContext();942 const injectedScript = await context.injectedScript();943 return await injectedScript.evaluate(injected => {944 return injected.hideHighlight();945 });946 }947 async _elementState(metadata, selector, state, options = {}) {948 const result = await this._scheduleRerunnableTask(metadata, selector, (progress, element, data) => {949 const injected = progress.injectedScript;950 return injected.elementState(element, data.state);951 }, {952 state953 }, options);954 return dom.throwRetargetableDOMError(result);955 }956 async isVisible(metadata, selector, options = {}) {957 const controller = new _progress.ProgressController(metadata, this);958 return controller.run(async progress => {959 progress.log(` checking visibility of "${selector}"`);960 const pair = await this.resolveFrameForSelectorNoWait(selector, options);961 if (!pair) return false;962 const element = await this._page.selectors.query(pair.frame, pair.info);963 return element ? await element.isVisible() : false;964 }, this._page._timeoutSettings.timeout({}));965 }966 async isHidden(metadata, selector, options = {}) {967 return !(await this.isVisible(metadata, selector, options));968 }969 async isDisabled(metadata, selector, options = {}) {970 return this._elementState(metadata, selector, 'disabled', options);971 }972 async isEnabled(metadata, selector, options = {}) {973 return this._elementState(metadata, selector, 'enabled', options);974 }975 async isEditable(metadata, selector, options = {}) {976 return this._elementState(metadata, selector, 'editable', options);977 }978 async isChecked(metadata, selector, options = {}) {979 return this._elementState(metadata, selector, 'checked', options);980 }981 async hover(metadata, selector, options = {}) {982 const controller = new _progress.ProgressController(metadata, this);983 return controller.run(async progress => {984 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options)));985 }, this._page._timeoutSettings.timeout(options));986 }987 async selectOption(metadata, selector, elements, values, options = {}) {988 const controller = new _progress.ProgressController(metadata, this);989 return controller.run(async progress => {990 return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._selectOption(progress, elements, values, options));991 }, this._page._timeoutSettings.timeout(options));992 }993 async setInputFiles(metadata, selector, files, options = {}) {994 const controller = new _progress.ProgressController(metadata, this);995 return controller.run(async progress => {996 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setInputFiles(progress, files, options)));997 }, this._page._timeoutSettings.timeout(options));998 }999 async type(metadata, selector, text, options = {}) {1000 const controller = new _progress.ProgressController(metadata, this);1001 return controller.run(async progress => {1002 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._type(progress, text, options)));1003 }, this._page._timeoutSettings.timeout(options));1004 }1005 async press(metadata, selector, key, options = {}) {1006 const controller = new _progress.ProgressController(metadata, this);1007 return controller.run(async progress => {1008 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._press(progress, key, options)));1009 }, this._page._timeoutSettings.timeout(options));1010 }1011 async check(metadata, selector, options = {}) {1012 const controller = new _progress.ProgressController(metadata, this);1013 return controller.run(async progress => {1014 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, true, options)));1015 }, this._page._timeoutSettings.timeout(options));1016 }1017 async uncheck(metadata, selector, options = {}) {1018 const controller = new _progress.ProgressController(metadata, this);1019 return controller.run(async progress => {1020 return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, false, options)));1021 }, this._page._timeoutSettings.timeout(options));1022 }1023 async waitForTimeout(metadata, timeout) {1024 const controller = new _progress.ProgressController(metadata, this);1025 return controller.run(async () => {1026 await new Promise(resolve => setTimeout(resolve, timeout));1027 });1028 }1029 async expect(metadata, selector, options) {1030 const controller = new _progress.ProgressController(metadata, this);1031 const isArray = options.expression === 'to.have.count' || options.expression.endsWith('.array');1032 const mainWorld = options.expression === 'to.have.property';1033 const timeout = this._page._timeoutSettings.timeout(options); // List all combinations that are satisfied with the detached node(s).1034 let omitAttached = false;1035 if (!options.isNot && options.expression === 'to.be.hidden') omitAttached = true;else if (options.isNot && options.expression === 'to.be.visible') omitAttached = true;else if (!options.isNot && options.expression === 'to.have.count' && options.expectedNumber === 0) omitAttached = true;else if (options.isNot && options.expression === 'to.have.count' && options.expectedNumber !== 0) omitAttached = true;else if (!options.isNot && options.expression.endsWith('.array') && options.expectedText.length === 0) omitAttached = true;else if (options.isNot && options.expression.endsWith('.array') && options.expectedText.length > 0) omitAttached = true;1036 return controller.run(async outerProgress => {1037 outerProgress.log(`${metadata.apiName}${timeout ? ` with timeout ${timeout}ms` : ''}`);1038 return await this._scheduleRerunnableTaskWithProgress(outerProgress, selector, (progress, element, options, elements) => {1039 let result;1040 if (options.isArray) {1041 result = progress.injectedScript.expectArray(elements, options);1042 } else {1043 if (!element) {1044 // expect(locator).toBeHidden() passes when there is no element.1045 if (!options.isNot && options.expression === 'to.be.hidden') return {1046 matches: true1047 }; // expect(locator).not.toBeVisible() passes when there is no element.1048 if (options.isNot && options.expression === 'to.be.visible') return {1049 matches: false1050 }; // When none of the above applies, keep waiting for the element.1051 return progress.continuePolling;1052 }1053 result = progress.injectedScript.expectSingleElement(progress, element, options);1054 }1055 if (result.matches === options.isNot) {1056 // Keep waiting in these cases:1057 // expect(locator).conditionThatDoesNotMatch1058 // expect(locator).not.conditionThatDoesMatch1059 progress.setIntermediateResult(result.received);1060 if (!Array.isArray(result.received)) progress.log(` unexpected value "${result.received}"`);1061 return progress.continuePolling;1062 } // Reached the expected state!1063 return result;1064 }, { ...options,1065 isArray1066 }, {1067 strict: true,1068 querySelectorAll: isArray,1069 mainWorld,1070 omitAttached,1071 logScale: true,1072 ...options1073 });1074 }, timeout).catch(e => {1075 // Q: Why not throw upon isSessionClosedError(e) as in other places?1076 // A: We want user to receive a friendly message containing the last intermediate result.1077 if (js.isJavaScriptErrorInEvaluate(e) || (0, _selectorErrors.isInvalidSelectorError)(e)) throw e;1078 return {1079 received: controller.lastIntermediateResult(),1080 matches: options.isNot,1081 log: metadata.log1082 };1083 });1084 }1085 async _waitForFunctionExpression(metadata, expression, isFunction, arg, options, world = 'main') {1086 const controller = new _progress.ProgressController(metadata, this);1087 if (typeof options.pollingInterval === 'number') (0, _utils.assert)(options.pollingInterval > 0, 'Cannot poll with non-positive interval: ' + options.pollingInterval);1088 expression = js.normalizeEvaluationExpression(expression, isFunction);1089 const task = injectedScript => injectedScript.evaluateHandle((injectedScript, {1090 expression,1091 isFunction,1092 polling,1093 arg1094 }) => {1095 const predicate = arg => {1096 let result = self.eval(expression);1097 if (isFunction === true) {1098 result = result(arg);1099 } else if (isFunction === false) {1100 result = result;1101 } else {1102 // auto detect.1103 if (typeof result === 'function') result = result(arg);1104 }1105 return result;1106 };1107 if (typeof polling !== 'number') return injectedScript.pollRaf(progress => predicate(arg) || progress.continuePolling);1108 return injectedScript.pollInterval(polling, progress => predicate(arg) || progress.continuePolling);1109 }, {1110 expression,1111 isFunction,1112 polling: options.pollingInterval,1113 arg1114 });1115 return controller.run(progress => this._scheduleRerunnableHandleTask(progress, world, task), this._page._timeoutSettings.timeout(options));1116 }1117 async waitForFunctionValueInUtility(progress, pageFunction) {1118 const expression = `() => {1119 const result = (${pageFunction})();1120 if (!result)1121 return result;1122 return JSON.stringify(result);1123 }`;1124 const handle = await this._waitForFunctionExpression((0, _instrumentation.internalCallMetadata)(), expression, true, undefined, {1125 timeout: progress.timeUntilDeadline()1126 }, 'utility');1127 return JSON.parse(handle.rawValue());1128 }1129 async title() {1130 const context = await this._utilityContext();1131 return context.evaluate(() => document.title);1132 }1133 _onDetached() {1134 this._stopNetworkIdleTimer();1135 this._detached = true;1136 this._detachedCallback();1137 const error = new Error('Frame was detached');1138 for (const data of this._contextData.values()) {1139 if (data.context) data.context.contextDestroyed(error);1140 data.contextPromise.resolve(error);1141 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.terminate(error);1142 }1143 if (this._parentFrame) this._parentFrame._childFrames.delete(this);1144 this._parentFrame = null;1145 }1146 async _scheduleRerunnableTask(metadata, selector, body, taskData, options = {}) {1147 const controller = new _progress.ProgressController(metadata, this);1148 return controller.run(async progress => {1149 return await this._scheduleRerunnableTaskWithProgress(progress, selector, body, taskData, options);1150 }, this._page._timeoutSettings.timeout(options));1151 }1152 async _scheduleRerunnableTaskWithProgress(progress, selector, body, taskData, options = {}) {1153 const callbackText = body.toString();1154 return this.retryWithProgress(progress, selector, options, async selectorInFrame => {1155 // Be careful, |this| can be different from |frame|.1156 progress.log(`waiting for selector "${selector}"`);1157 const {1158 frame,1159 info1160 } = selectorInFrame || {1161 frame: this,1162 info: {1163 parsed: {1164 parts: [{1165 name: 'control',1166 body: 'return-empty',1167 source: 'control=return-empty'1168 }]1169 },1170 world: 'utility',1171 strict: !!options.strict1172 }1173 };1174 return await frame._scheduleRerunnableTaskInFrame(progress, info, callbackText, taskData, options);1175 });1176 }1177 async _scheduleRerunnableTaskInFrame(progress, info, callbackText, taskData, options) {1178 progress.throwIfAborted();1179 const data = this._contextData.get(options.mainWorld ? 'main' : info.world); // This potentially runs in a sub-frame.1180 {1181 const rerunnableTask = new RerunnableTask(data, progress, injectedScript => {1182 return injectedScript.evaluateHandle((injected, {1183 info,1184 taskData,1185 callbackText,1186 querySelectorAll,1187 logScale,1188 omitAttached,1189 snapshotName1190 }) => {1191 const callback = injected.eval(callbackText);1192 const poller = logScale ? injected.pollLogScale.bind(injected) : injected.pollRaf.bind(injected);1193 let markedElements = new Set();1194 return poller(progress => {1195 let element;1196 let elements = [];1197 if (querySelectorAll) {1198 elements = injected.querySelectorAll(info.parsed, document);1199 element = elements[0];1200 progress.logRepeating(` selector resolved to ${elements.length} element${elements.length === 1 ? '' : 's'}`);1201 } else {1202 element = injected.querySelector(info.parsed, document, info.strict);1203 elements = element ? [element] : [];1204 if (element) progress.logRepeating(` selector resolved to ${injected.previewNode(element)}`);1205 }1206 if (!element && !omitAttached) return progress.continuePolling;1207 if (snapshotName) {1208 const previouslyMarkedElements = markedElements;1209 markedElements = new Set(elements);1210 for (const e of previouslyMarkedElements) {1211 if (!markedElements.has(e)) e.removeAttribute('__playwright_target__');1212 }1213 for (const e of markedElements) {1214 if (!previouslyMarkedElements.has(e)) e.setAttribute('__playwright_target__', snapshotName);1215 }1216 }1217 return callback(progress, element, taskData, elements);1218 });1219 }, {1220 info,1221 taskData,1222 callbackText,1223 querySelectorAll: options.querySelectorAll,1224 logScale: options.logScale,1225 omitAttached: options.omitAttached,1226 snapshotName: progress.metadata.afterSnapshot1227 });1228 }, true);1229 if (this._detached) rerunnableTask.terminate(new Error('Frame got detached.'));1230 if (data.context) rerunnableTask.rerun(data.context);1231 return await rerunnableTask.promise;1232 }1233 }1234 _scheduleRerunnableHandleTask(progress, world, task) {1235 const data = this._contextData.get(world);1236 const rerunnableTask = new RerunnableTask(data, progress, task, false1237 /* returnByValue */1238 );1239 if (this._detached) rerunnableTask.terminate(new Error('waitForFunction failed: frame got detached.'));1240 if (data.context) rerunnableTask.rerun(data.context);1241 return rerunnableTask.handlePromise;1242 }1243 _setContext(world, context) {1244 const data = this._contextData.get(world);1245 data.context = context;1246 if (context) {1247 data.contextPromise.resolve(context);1248 for (const rerunnableTask of data.rerunnableTasks) rerunnableTask.rerun(context);1249 } else {1250 data.contextPromise = new _async.ManualPromise();1251 }1252 }1253 _contextCreated(world, context) {1254 const data = this._contextData.get(world); // In case of multiple sessions to the same target, there's a race between1255 // connections so we might end up creating multiple isolated worlds.1256 // We can use either.1257 if (data.context) {1258 data.context.contextDestroyed(new Error('Execution context was destroyed, most likely because of a navigation'));1259 this._setContext(world, null);1260 }1261 this._setContext(world, context);1262 }1263 _contextDestroyed(context) {1264 // Sometimes we get this after detach, in which case we should not reset1265 // our already destroyed contexts to something that will never resolve.1266 if (this._detached) return;1267 context.contextDestroyed(new Error('Execution context was destroyed, most likely because of a navigation'));1268 for (const [world, data] of this._contextData) {1269 if (data.context === context) this._setContext(world, null);1270 }1271 }1272 _startNetworkIdleTimer() {1273 (0, _utils.assert)(!this._networkIdleTimer); // We should not start a timer and report networkidle in detached frames.1274 // This happens at least in Firefox for child frames, where we may get requestFinished1275 // after the frame was detached - probably a race in the Firefox itself.1276 if (this._firedLifecycleEvents.has('networkidle') || this._detached) return;1277 this._networkIdleTimer = setTimeout(() => this._onLifecycleEvent('networkidle'), 500);1278 }1279 _stopNetworkIdleTimer() {1280 if (this._networkIdleTimer) clearTimeout(this._networkIdleTimer);1281 this._networkIdleTimer = undefined;1282 }1283 async extendInjectedScript(source, arg) {1284 const context = await this._context('main');1285 const injectedScriptHandle = await context.injectedScript();1286 return injectedScriptHandle.evaluateHandle((injectedScript, {1287 source,1288 arg1289 }) => {1290 return injectedScript.extend(source, arg);1291 }, {1292 source,1293 arg1294 });1295 }1296 async _resolveFrameForSelector(progress, selector, options, scope) {1297 const elementPath = [];1298 progress.cleanupWhenAborted(() => {1299 // Do not await here to avoid being blocked, either by stalled1300 // page (e.g. alert) or unresolved navigation in Chromium.1301 for (const element of elementPath) element.dispose();1302 });1303 let frame = this;1304 const frameChunks = (0, _selectorParser.splitSelectorByFrame)(selector);1305 for (let i = 0; i < frameChunks.length - 1 && progress.isRunning(); ++i) {1306 const info = this._page.parseSelector(frameChunks[i], options);1307 const task = dom.waitForSelectorTask(info, 'attached', false, i === 0 ? scope : undefined);1308 progress.log(` waiting for frame "${(0, _selectorParser.stringifySelector)(frameChunks[i])}"`);1309 const handle = i === 0 && scope ? await frame._runWaitForSelectorTaskOnce(progress, (0, _selectorParser.stringifySelector)(info.parsed), info.world, task) : await frame._scheduleRerunnableHandleTask(progress, info.world, task);1310 const element = handle.asElement();1311 const isIframe = await element.isIframeElement();1312 if (isIframe === 'error:notconnected') return null; // retry1313 if (!isIframe) throw new Error(`Selector "${(0, _selectorParser.stringifySelector)(info.parsed)}" resolved to ${element.preview()}, <iframe> was expected`);1314 frame = await element.contentFrame();1315 element.dispose();1316 if (!frame) return null; // retry1317 }1318 return {1319 frame,1320 info: this._page.parseSelector(frameChunks[frameChunks.length - 1], options)1321 };...

Full Screen

Full Screen

dom.js

Source:dom.js Github

copy

Full Screen

...1095 throw new Error(1096 `state: expected one of (attached|detached|visible|hidden)`1097 )1098 const info = this._page.parseSelector(selector, options)1099 const task = waitForSelectorTask(info, state, false, this)1100 const controller = new _progress.ProgressController(metadata, this)1101 return controller.run(async (progress) => {1102 progress.log(1103 `waiting for selector "${selector}"${1104 state === 'attached' ? '' : ' to be ' + state1105 }`1106 )1107 const context = await this._context.frame._context(info.world)1108 const injected = await context.injectedScript()1109 const pollHandler = new InjectedScriptPollHandler(1110 progress,1111 await task(injected)1112 )1113 const result = await pollHandler.finishHandle()1114 if (!result.asElement()) {1115 result.dispose()1116 return null1117 }1118 const handle = result.asElement()1119 return handle._adoptTo(await this._context.frame._mainContext())1120 }, this._page._timeoutSettings.timeout(options))1121 }1122 async _adoptTo(context) {1123 if (this._context !== context) {1124 const adopted = await this._page._delegate.adoptElementHandle(1125 this,1126 context1127 )1128 this.dispose()1129 return adopted1130 }1131 return this1132 }1133 async _waitForDisplayedAtStablePosition(progress, force, waitForEnabled) {1134 if (waitForEnabled)1135 progress.log(` waiting for element to be visible, enabled and stable`)1136 else progress.log(` waiting for element to be visible and stable`)1137 const result = await this.evaluatePoll(1138 progress,1139 ([injected, node, { waitForEnabled, force }]) => {1140 return injected.waitForElementStatesAndPerformAction(1141 node,1142 waitForEnabled1143 ? ['visible', 'stable', 'enabled']1144 : ['visible', 'stable'],1145 force,1146 () => 'done'1147 )1148 },1149 {1150 waitForEnabled,1151 force1152 }1153 )1154 if (result === 'error:notconnected') return result1155 if (waitForEnabled) progress.log(' element is visible, enabled and stable')1156 else progress.log(' element is visible and stable')1157 return result1158 }1159 async _checkHitTargetAt(point) {1160 const frame = await this.ownerFrame()1161 if (frame && frame.parentFrame()) {1162 const element = await frame.frameElement()1163 const box = await element.boundingBox()1164 if (!box) return 'error:notconnected' // Translate from viewport coordinates to frame coordinates.1165 point = {1166 x: point.x - box.x,1167 y: point.y - box.y1168 }1169 }1170 return this.evaluateInUtility(1171 ([injected, node, point]) => injected.checkHitTargetAt(node, point),1172 point1173 )1174 }1175} // Handles an InjectedScriptPoll running in injected script:1176// - streams logs into progress;1177// - cancels the poll when progress cancels.1178exports.ElementHandle = ElementHandle1179class InjectedScriptPollHandler {1180 constructor(progress, poll) {1181 this._progress = void 01182 this._poll = void 01183 this._progress = progress1184 this._poll = poll // Ensure we cancel the poll before progress aborts and returns:1185 // - no unnecessary work in the page;1186 // - no possible side effects after progress promsie rejects.1187 this._progress.cleanupWhenAborted(() => this.cancel())1188 this._streamLogs()1189 }1190 async _streamLogs() {1191 while (this._poll && this._progress.isRunning()) {1192 const log = await this._poll1193 .evaluate((poll) => poll.takeNextLogs())1194 .catch((e) => [])1195 if (!this._poll || !this._progress.isRunning()) return1196 for (const entry of log) this._progress.logEntry(entry)1197 }1198 }1199 async finishHandle() {1200 try {1201 const result = await this._poll.evaluateHandle((poll) => poll.run())1202 await this._finishInternal()1203 return result1204 } finally {1205 await this.cancel()1206 }1207 }1208 async finish() {1209 try {1210 const result = await this._poll.evaluate((poll) => poll.run())1211 await this._finishInternal()1212 return result1213 } finally {1214 await this.cancel()1215 }1216 }1217 async _finishInternal() {1218 if (!this._poll) return // Retrieve all the logs before continuing.1219 const log = await this._poll1220 .evaluate((poll) => poll.takeLastLogs())1221 .catch((e) => [])1222 for (const entry of log) this._progress.logEntry(entry)1223 }1224 async cancel() {1225 if (!this._poll) return1226 const copy = this._poll1227 this._poll = null1228 await copy.evaluate((p) => p.cancel()).catch((e) => {})1229 copy.dispose()1230 }1231}1232exports.InjectedScriptPollHandler = InjectedScriptPollHandler1233function throwRetargetableDOMError(result) {1234 if (result === 'error:notconnected')1235 throw new Error('Element is not attached to the DOM')1236 return result1237}1238function assertDone(result) {1239 // This function converts 'done' to void and ensures typescript catches unhandled errors.1240}1241function roundPoint(point) {1242 return {1243 x: ((point.x * 100) | 0) / 100,1244 y: ((point.y * 100) | 0) / 1001245 }1246}1247function compensateHalfIntegerRoundingError(point) {1248 // Firefox internally uses integer coordinates, so 8.5 is converted to 9 when clicking.1249 //1250 // This does not work nicely for small elements. For example, 1x1 square with corners1251 // (8;8) and (9;9) is targeted when clicking at (8;8) but not when clicking at (9;9).1252 // So, clicking at (8.5;8.5) will effectively click at (9;9) and miss the target.1253 //1254 // Therefore, we skew half-integer values from the interval (8.49, 8.51) towards1255 // (8.47, 8.49) that is rounded towards 8. This means clicking at (8.5;8.5) will1256 // be replaced with (8.48;8.48) and will effectively click at (8;8).1257 //1258 // Other browsers use float coordinates, so this change should not matter.1259 const remainderX = point.x - Math.floor(point.x)1260 if (remainderX > 0.49 && remainderX < 0.51) point.x -= 0.021261 const remainderY = point.y - Math.floor(point.y)1262 if (remainderY > 0.49 && remainderY < 0.51) point.y -= 0.021263}1264function waitForSelectorTask(selector, state, omitReturnValue, root) {1265 return (injectedScript) =>1266 injectedScript.evaluateHandle(1267 (injected, { parsed, strict, state, omitReturnValue, root }) => {1268 let lastElement1269 return injected.pollRaf((progress) => {1270 const elements = injected.querySelectorAll(parsed, root || document)1271 let element = elements[0]1272 const visible = element ? injected.isVisible(element) : false1273 if (lastElement !== element) {1274 lastElement = element1275 if (!element) {1276 progress.log(` selector did not resolve to any element`)1277 } else {1278 if (elements.length > 1) {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const element = await page.waitForSelectorTask('text=Get Started');7 await element.click();8 await browser.close();9})();10module.exports = {11 use: {12 viewport: { width: 1280, height: 720 },13 },14 {15 use: {16 },17 },18};19module.exports = {20 use: {21 viewport: { width: 1280, height: 720 },22 },23 {24 use: {25 },26 },27};28module.exports = {29 use: {30 viewport: { width: 1280, height: 720 },31 },32 {33 use: {34 },35 },36};37module.exports = {38 use: {39 viewport: { width: 1280, height: 720 },

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright['chromium'].launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForSelector('text=Get Started');7 await browser.close();8})();9module.exports = {10 use: {11 viewport: { width: 1280, height: 720 },12 },13};

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2const { waitForSelectorTask } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');3(async () => {4 const browser = await playwright['chromium'].launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('input[name="q"]');8 await waitForSelectorTask(page, 'input[name="q"]');9 await page.fill('input[name="q"]', 'Hello World!');10 await page.keyboard.press('Enter');11 await page.waitForSelector('text=Hello World!');12 await page.click('text=Hello World!');13 await page.waitForSelector('text=Hello World! - Google Search');14 await page.click('text=Hello World! - Google Search');15 await page.waitForSelector('text=Hello World! - Google Search');16 await page.click('text=Hello World! - Google Search');17 await page.waitForSelector('text=Hello World! - Google Search');18 await page.click('text=Hello World! - Google Search');19 await page.waitForSelector('text=Hello World! - Google Search');20 await page.click('text=Hello World! - Google Search');21 await page.waitForSelector('text=Hello World! - Google Search');22 await page.click('text=Hello World! - Google Search');23 await page.waitForSelector('text=Hello World! - Google Search');24 await page.click('text=Hello World! - Google Search');25 await page.waitForSelector('text=Hello World! - Google Search');26 await page.click('text=Hello World! - Google Search');27 await page.waitForSelector('text=Hello World! - Google Search');28 await page.click('text=Hello World! - Google Search');29 await page.waitForSelector('text=Hello World! - Google Search');30 await page.click('text=Hello World! - Google Search');31 await page.waitForSelector('text=Hello World! - Google Search');32 await page.click('text=Hello World! - Google Search');33 await page.waitForSelector('text=Hello World! - Google Search');34 await page.click('text=Hello World! - Google Search');35 await page.waitForSelector('text=Hello World! - Google Search');36 await page.click('text=Hello World! - Google Search');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForSelectorTask } = require('@playwright/test/lib/server/frames');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await waitForSelectorTask(page.mainFrame(), 'input[name="btnK"]', { state: 'visible', timeout: 3000 });8 await page.screenshot({ path: 'google.png' });9 await browser.close();10})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForSelectorTask } = require('playwright/lib/server/frames');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await waitForSelectorTask(page.mainFrame(), 'button', {8 });9 await page.click('button');10 await browser.close();11})();12const { chromium } = require('playwright');13describe('TodoMVC', () => {14 it('should add a todo', async () => {15 const browser = await chromium.launch();16 const context = await browser.newContext();17 const page = await context.newPage();18 await page.waitForSelector('button');19 await page.click('button');20 await browser.close();21 });22});23const { chromium } = require('playwright');24describe('TodoMVC', () => {25 it('should add a todo', async () => {26 const browser = await chromium.launch();27 const context = await browser.newContext();28 const page = await context.newPage();29 await page.waitForSelector('button');30 await page.click('button');31 await browser.close();32 });33});34const { chromium } = require('playwright');35describe('TodoMVC', () => {36 it('should add a todo', async () => {37 const browser = await chromium.launch();38 const context = await browser.newContext();39 const page = await context.newPage();40 await page.waitForSelector('button');41 await page.click('

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForSelectorTask } = require('playwright/lib/protocol/protocol');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('input[name="q"]');8 await page.type('input[name="q"]', 'playwright');9 await page.keyboard.press('Enter');10 await page.waitForSelector('text=Playwright');11 await page.waitForTimeout(1000);12 await page.screenshot({ path: 'example.png' });13 await browser.close();14})();15const { waitForSelectorTask } = require('playwright/lib/protocol/protocol');16const { chromium } = require('playwright');17(async () => {18 const browser = await chromium.launch();19 const context = await browser.newContext();20 const page = await context.newPage();21 await page.click('input[name="q"]');22 await page.type('input[name="q"]', 'playwright');23 await page.keyboard.press('Enter');24 await page.waitForSelector('text=Playwright', { waitUntil: 'domcontentloaded' });25 await page.waitForTimeout(1000);26 await page.screenshot({ path: 'example.png' });27 await browser.close();28})();29const { waitForSelectorTask } = require('playwright/lib/protocol/protocol');30const { chromium } = require('playwright');31(async () => {32 const browser = await chromium.launch();33 const context = await browser.newContext();34 const page = await context.newPage();35 await page.click('input[name="q"]');36 await page.type('input[name="q"]', 'playwright');37 await page.keyboard.press('Enter');38 await page.waitForSelector('text=Playwright', { timeout: 5000 });39 await page.waitForTimeout(1000);40 await page.screenshot({ path: 'example.png' });41 await browser.close();42})();43const { waitForSelectorTask } = require('playwright

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForSelectorTask } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await waitForSelectorTask(page, 'css=div');7 await browser.close();8})();9const { waitForSelectorTask } = require('playwright/lib/server/supplements/recorder/recorderSupplement');10const { chromium } = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const page = await browser.newPage();14 await waitForSelectorTask(page, 'css=div');15 await browser.close();16})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForSelectorTask('text=Get started');7 await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const context = await browser.newContext();13 const page = await context.newPage();14 await page.waitForSelectorTask('text=Get started', { state: 'hidden' });15 await browser.close();16})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForSelectorTask } = require('playwright-core/lib/server/supplements/recorder/recorderSupplement');2const { firefox } = require('playwright-core');3(async () => {4 const browser = await firefox.launch();5 const page = await browser.newPage();6 await waitForSelectorTask(page, 'text=Example Domain');7 await page.screenshot({ path: 'example.png' });8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1var { waitForSelectorTask } = require('playwright/lib/server/page');2(async () => {3 await waitForSelectorTask({4 });5})();6const { test, expect } = require('@playwright/test');7test('my test', async ({ page }) => {8 await page.waitForSelector('text=Get Started');9 const title = await page.innerText('h1');10 expect(title).toBe('Playwright');11});12const { test, expect } = require('@playwright/test');13test('my test', async ({ page }) => {14 await page.waitForSelector('text=Get Started');15 const title = await page.innerText('h1');16 expect(title).toBe('Playwright');17});

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful