How to use _updateOffline method in Playwright Internal

Best JavaScript code snippet using playwright-internal

crPage.js

Source:crPage.js Github

copy

Full Screen

...162 async updateGeolocation() {163 await this._forAllFrameSessions(frame => frame._updateGeolocation(false));164 }165 async updateOffline() {166 await this._forAllFrameSessions(frame => frame._updateOffline(false));167 }168 async updateHttpCredentials() {169 await this._forAllFrameSessions(frame => frame._updateHttpCredentials(false));170 }171 async setEmulatedSize(emulatedSize) {172 (0, _utils.assert)(this._page._state.emulatedSize === emulatedSize);173 await this._mainFrameSession._updateViewport();174 }175 async bringToFront() {176 await this._mainFrameSession._client.send('Page.bringToFront');177 }178 async updateEmulateMedia() {179 await this._forAllFrameSessions(frame => frame._updateEmulateMedia(false));180 }181 async updateRequestInterception() {182 await this._forAllFrameSessions(frame => frame._updateRequestInterception());183 }184 async setFileChooserIntercepted(enabled) {185 await this._forAllFrameSessions(frame => frame._setFileChooserIntercepted(enabled));186 }187 async reload() {188 await this._mainFrameSession._client.send('Page.reload');189 }190 async _go(delta) {191 const history = await this._mainFrameSession._client.send('Page.getNavigationHistory');192 const entry = history.entries[history.currentIndex + delta];193 if (!entry) return false;194 await this._mainFrameSession._client.send('Page.navigateToHistoryEntry', {195 entryId: entry.id196 });197 return true;198 }199 goBack() {200 return this._go(-1);201 }202 goForward() {203 return this._go(+1);204 }205 async evaluateOnNewDocument(source, world = 'main') {206 await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(source, world));207 }208 async closePage(runBeforeUnload) {209 if (runBeforeUnload) await this._mainFrameSession._client.send('Page.close');else await this._browserContext._browser._closePage(this);210 }211 async setBackgroundColor(color) {212 await this._mainFrameSession._client.send('Emulation.setDefaultBackgroundColorOverride', {213 color214 });215 }216 async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport) {217 const {218 visualViewport219 } = await this._mainFrameSession._client.send('Page.getLayoutMetrics');220 if (!documentRect) {221 documentRect = {222 x: visualViewport.pageX + viewportRect.x,223 y: visualViewport.pageY + viewportRect.y,224 ..._helper.helper.enclosingIntSize({225 width: viewportRect.width / visualViewport.scale,226 height: viewportRect.height / visualViewport.scale227 })228 };229 } // When taking screenshots with documentRect (based on the page content, not viewport),230 // ignore current page scale.231 const clip = { ...documentRect,232 scale: viewportRect ? visualViewport.scale : 1233 };234 progress.throwIfAborted();235 const result = await this._mainFrameSession._client.send('Page.captureScreenshot', {236 format,237 quality,238 clip,239 captureBeyondViewport: !fitsViewport240 });241 return Buffer.from(result.data, 'base64');242 }243 async getContentFrame(handle) {244 return this._sessionForHandle(handle)._getContentFrame(handle);245 }246 async getOwnerFrame(handle) {247 return this._sessionForHandle(handle)._getOwnerFrame(handle);248 }249 isElementHandle(remoteObject) {250 return remoteObject.subtype === 'node';251 }252 async getBoundingBox(handle) {253 return this._sessionForHandle(handle)._getBoundingBox(handle);254 }255 async scrollRectIntoViewIfNeeded(handle, rect) {256 return this._sessionForHandle(handle)._scrollRectIntoViewIfNeeded(handle, rect);257 }258 async setScreencastOptions(options) {259 if (options) {260 await this._mainFrameSession._startScreencast(this, {261 format: 'jpeg',262 quality: options.quality,263 maxWidth: options.width,264 maxHeight: options.height265 });266 } else {267 await this._mainFrameSession._stopScreencast(this);268 }269 }270 rafCountForStablePosition() {271 return 1;272 }273 async getContentQuads(handle) {274 return this._sessionForHandle(handle)._getContentQuads(handle);275 }276 async setInputFiles(handle, files) {277 await handle.evaluateInUtility(([injected, node, files]) => injected.setInputFiles(node, files), files);278 }279 async adoptElementHandle(handle, to) {280 return this._sessionForHandle(handle)._adoptElementHandle(handle, to);281 }282 async getAccessibilityTree(needle) {283 return (0, _crAccessibility.getAccessibilityTree)(this._mainFrameSession._client, needle);284 }285 async inputActionEpilogue() {286 await this._mainFrameSession._client.send('Page.enable').catch(e => {});287 }288 async pdf(options) {289 return this._pdf.generate(options);290 }291 coverage() {292 return this._coverage;293 }294 async getFrameElement(frame) {295 let parent = frame.parentFrame();296 if (!parent) throw new Error('Frame has been detached.');297 const parentSession = this._sessionForFrame(parent);298 const {299 backendNodeId300 } = await parentSession._client.send('DOM.getFrameOwner', {301 frameId: frame._id302 }).catch(e => {303 if (e instanceof Error && e.message.includes('Frame with the given id was not found.')) (0, _stackTrace.rewriteErrorMessage)(e, 'Frame has been detached.');304 throw e;305 });306 parent = frame.parentFrame();307 if (!parent) throw new Error('Frame has been detached.');308 return parentSession._adoptBackendNodeId(backendNodeId, await parent._mainContext());309 }310}311exports.CRPage = CRPage;312class FrameSession {313 // Marks the oopif session that remote -> local transition has happened in the parent.314 // See Target.detachedFromTarget handler for details.315 constructor(crPage, client, targetId, parentSession) {316 this._client = void 0;317 this._crPage = void 0;318 this._page = void 0;319 this._networkManager = void 0;320 this._contextIdToContext = new Map();321 this._eventListeners = [];322 this._targetId = void 0;323 this._firstNonInitialNavigationCommittedPromise = void 0;324 this._firstNonInitialNavigationCommittedFulfill = () => {};325 this._firstNonInitialNavigationCommittedReject = e => {};326 this._windowId = void 0;327 this._swappedIn = false;328 this._videoRecorder = null;329 this._screencastId = null;330 this._screencastClients = new Set();331 this._client = client;332 this._crPage = crPage;333 this._page = crPage._page;334 this._targetId = targetId;335 this._networkManager = new _crNetworkManager.CRNetworkManager(client, this._page, parentSession ? parentSession._networkManager : null);336 this._firstNonInitialNavigationCommittedPromise = new Promise((f, r) => {337 this._firstNonInitialNavigationCommittedFulfill = f;338 this._firstNonInitialNavigationCommittedReject = r;339 });340 client.once(_crConnection.CRSessionEvents.Disconnected, () => {341 this._firstNonInitialNavigationCommittedReject(new Error('Page closed'));342 });343 }344 _isMainFrame() {345 return this._targetId === this._crPage._targetId;346 }347 _addRendererListeners() {348 this._eventListeners.push(...[_eventsHelper.eventsHelper.addEventListener(this._client, 'Log.entryAdded', event => this._onLogEntryAdded(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.fileChooserOpened', event => this._onFileChooserOpened(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameAttached', event => this._onFrameAttached(event.frameId, event.parentFrameId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameDetached', event => this._onFrameDetached(event.frameId, event.reason)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameNavigated', event => this._onFrameNavigated(event.frame, false)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameRequestedNavigation', event => this._onFrameRequestedNavigation(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.frameStoppedLoading', event => this._onFrameStoppedLoading(event.frameId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.javascriptDialogOpening', event => this._onDialog(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.navigatedWithinDocument', event => this._onFrameNavigatedWithinDocument(event.frameId, event.url)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.bindingCalled', event => this._onBindingCalled(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.consoleAPICalled', event => this._onConsoleAPI(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.exceptionThrown', exception => this._handleException(exception.exceptionDetails)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextCreated', event => this._onExecutionContextCreated(event.context)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextDestroyed', event => this._onExecutionContextDestroyed(event.executionContextId)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Runtime.executionContextsCleared', event => this._onExecutionContextsCleared()), _eventsHelper.eventsHelper.addEventListener(this._client, 'Target.attachedToTarget', event => this._onAttachedToTarget(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Target.detachedFromTarget', event => this._onDetachedFromTarget(event))]);349 }350 _addBrowserListeners() {351 this._eventListeners.push(...[_eventsHelper.eventsHelper.addEventListener(this._client, 'Inspector.targetCrashed', event => this._onTargetCrashed()), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.screencastFrame', event => this._onScreencastFrame(event)), _eventsHelper.eventsHelper.addEventListener(this._client, 'Page.windowOpen', event => this._onWindowOpen(event))]);352 }353 async _initialize(hasUIWindow) {354 if (hasUIWindow && !this._crPage._browserContext._browser.isClank() && !this._crPage._browserContext._options.noDefaultViewport) {355 const {356 windowId357 } = await this._client.send('Browser.getWindowForTarget');358 this._windowId = windowId;359 }360 let screencastOptions;361 if (this._isMainFrame() && this._crPage._browserContext._options.recordVideo && hasUIWindow) {362 const screencastId = (0, _utils.createGuid)();363 const outputFile = _path.default.join(this._crPage._browserContext._options.recordVideo.dir, screencastId + '.webm');364 screencastOptions = { // validateBrowserContextOptions ensures correct video size.365 ...this._crPage._browserContext._options.recordVideo.size,366 outputFile367 };368 await this._crPage._browserContext._ensureVideosPath(); // Note: it is important to start video recorder before sending Page.startScreencast,369 // and it is equally important to send Page.startScreencast before sending Runtime.runIfWaitingForDebugger.370 await this._createVideoRecorder(screencastId, screencastOptions);371 this._crPage.pageOrError().then(p => {372 if (p instanceof Error) this._stopVideoRecording().catch(() => {});373 });374 }375 let lifecycleEventsEnabled;376 if (!this._isMainFrame()) this._addRendererListeners();377 this._addBrowserListeners();378 const promises = [this._client.send('Page.enable'), this._client.send('Page.getFrameTree').then(({379 frameTree380 }) => {381 if (this._isMainFrame()) {382 this._handleFrameTree(frameTree);383 this._addRendererListeners();384 }385 const localFrames = this._isMainFrame() ? this._page.frames() : [this._page._frameManager.frame(this._targetId)];386 for (const frame of localFrames) {387 // Note: frames might be removed before we send these.388 this._client._sendMayFail('Page.createIsolatedWorld', {389 frameId: frame._id,390 grantUniveralAccess: true,391 worldName: UTILITY_WORLD_NAME392 });393 for (const binding of this._crPage._browserContext._pageBindings.values()) frame.evaluateExpression(binding.source, false, undefined).catch(e => {});394 for (const source of this._crPage._browserContext._evaluateOnNewDocumentSources) frame.evaluateExpression(source, false, undefined, 'main').catch(e => {});395 }396 const isInitialEmptyPage = this._isMainFrame() && this._page.mainFrame().url() === ':';397 if (isInitialEmptyPage) {398 // Ignore lifecycle events for the initial empty page. It is never the final page399 // hence we are going to get more lifecycle updates after the actual navigation has400 // started (even if the target url is about:blank).401 lifecycleEventsEnabled.catch(e => {}).then(() => {402 this._eventListeners.push(_eventsHelper.eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event)));403 });404 } else {405 this._firstNonInitialNavigationCommittedFulfill();406 this._eventListeners.push(_eventsHelper.eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event)));407 }408 }), this._client.send('Log.enable', {}), lifecycleEventsEnabled = this._client.send('Page.setLifecycleEventsEnabled', {409 enabled: true410 }), this._client.send('Runtime.enable', {}), this._client.send('Page.addScriptToEvaluateOnNewDocument', {411 source: '',412 worldName: UTILITY_WORLD_NAME413 }), this._networkManager.initialize(), this._client.send('Target.setAutoAttach', {414 autoAttach: true,415 waitForDebuggerOnStart: true,416 flatten: true417 })];418 if (this._isMainFrame()) promises.push(this._client.send('Emulation.setFocusEmulationEnabled', {419 enabled: true420 }));421 const options = this._crPage._browserContext._options;422 if (options.bypassCSP) promises.push(this._client.send('Page.setBypassCSP', {423 enabled: true424 }));425 if (options.ignoreHTTPSErrors) promises.push(this._client.send('Security.setIgnoreCertificateErrors', {426 ignore: true427 }));428 if (this._isMainFrame()) promises.push(this._updateViewport());429 if (options.hasTouch) promises.push(this._client.send('Emulation.setTouchEmulationEnabled', {430 enabled: true431 }));432 if (options.javaScriptEnabled === false) promises.push(this._client.send('Emulation.setScriptExecutionDisabled', {433 value: true434 }));435 if (options.userAgent || options.locale) promises.push(this._client.send('Emulation.setUserAgentOverride', {436 userAgent: options.userAgent || '',437 acceptLanguage: options.locale438 }));439 if (options.locale) promises.push(emulateLocale(this._client, options.locale));440 if (options.timezoneId) promises.push(emulateTimezone(this._client, options.timezoneId));441 promises.push(this._updateGeolocation(true));442 promises.push(this._updateExtraHTTPHeaders(true));443 promises.push(this._updateRequestInterception());444 promises.push(this._updateOffline(true));445 promises.push(this._updateHttpCredentials(true));446 promises.push(this._updateEmulateMedia(true));447 for (const binding of this._crPage._page.allBindings()) promises.push(this._initBinding(binding));448 for (const source of this._crPage._browserContext._evaluateOnNewDocumentSources) promises.push(this._evaluateOnNewDocument(source, 'main'));449 for (const source of this._crPage._page._evaluateOnNewDocumentSources) promises.push(this._evaluateOnNewDocument(source, 'main'));450 if (screencastOptions) promises.push(this._startVideoRecording(screencastOptions));451 promises.push(this._client.send('Runtime.runIfWaitingForDebugger'));452 promises.push(this._firstNonInitialNavigationCommittedPromise);453 await Promise.all(promises);454 }455 dispose() {456 _eventsHelper.eventsHelper.removeEventListeners(this._eventListeners);457 this._networkManager.dispose();458 this._crPage._sessions.delete(this._targetId);459 }460 async _navigate(frame, url, referrer) {461 const response = await this._client.send('Page.navigate', {462 url,463 referrer,464 frameId: frame._id465 });466 if (response.errorText) throw new Error(`${response.errorText} at ${url}`);467 return {468 newDocumentId: response.loaderId469 };470 }471 _onLifecycleEvent(event) {472 if (this._eventBelongsToStaleFrame(event.frameId)) return;473 if (event.name === 'load') this._page._frameManager.frameLifecycleEvent(event.frameId, 'load');else if (event.name === 'DOMContentLoaded') this._page._frameManager.frameLifecycleEvent(event.frameId, 'domcontentloaded');474 }475 _onFrameStoppedLoading(frameId) {476 if (this._eventBelongsToStaleFrame(frameId)) return;477 this._page._frameManager.frameStoppedLoading(frameId);478 }479 _handleFrameTree(frameTree) {480 this._onFrameAttached(frameTree.frame.id, frameTree.frame.parentId || null);481 this._onFrameNavigated(frameTree.frame, true);482 if (!frameTree.childFrames) return;483 for (const child of frameTree.childFrames) this._handleFrameTree(child);484 }485 _eventBelongsToStaleFrame(frameId) {486 const frame = this._page._frameManager.frame(frameId); // Subtree may be already gone because some ancestor navigation destroyed the oopif.487 if (!frame) return true; // When frame goes remote, parent process may still send some events488 // related to the local frame before it sends frameDetached.489 // In this case, we already have a new session for this frame, so events490 // in the old session should be ignored.491 const session = this._crPage._sessionForFrame(frame);492 return session && session !== this && !session._swappedIn;493 }494 _onFrameAttached(frameId, parentFrameId) {495 const frameSession = this._crPage._sessions.get(frameId);496 if (frameSession && frameId !== this._targetId) {497 // This is a remote -> local frame transition.498 frameSession._swappedIn = true;499 const frame = this._page._frameManager.frame(frameId); // Frame or even a whole subtree may be already gone, because some ancestor did navigate.500 if (frame) this._page._frameManager.removeChildFramesRecursively(frame);501 return;502 }503 if (parentFrameId && !this._page._frameManager.frame(parentFrameId)) {504 // Parent frame may be gone already because some ancestor frame navigated and505 // destroyed the whole subtree of some oopif, while oopif's process is still sending us events.506 // Be careful to not confuse this with "main frame navigated cross-process" scenario507 // where parentFrameId is null.508 return;509 }510 this._page._frameManager.frameAttached(frameId, parentFrameId);511 }512 _onFrameNavigated(framePayload, initial) {513 if (this._eventBelongsToStaleFrame(framePayload.id)) return;514 this._page._frameManager.frameCommittedNewDocumentNavigation(framePayload.id, framePayload.url + (framePayload.urlFragment || ''), framePayload.name || '', framePayload.loaderId, initial);515 if (!initial) this._firstNonInitialNavigationCommittedFulfill();516 }517 _onFrameRequestedNavigation(payload) {518 if (this._eventBelongsToStaleFrame(payload.frameId)) return;519 if (payload.disposition === 'currentTab') this._page._frameManager.frameRequestedNavigation(payload.frameId);520 }521 _onFrameNavigatedWithinDocument(frameId, url) {522 if (this._eventBelongsToStaleFrame(frameId)) return;523 this._page._frameManager.frameCommittedSameDocumentNavigation(frameId, url);524 }525 _onFrameDetached(frameId, reason) {526 if (this._crPage._sessions.has(frameId)) {527 // This is a local -> remote frame transtion, where528 // Page.frameDetached arrives after Target.attachedToTarget.529 // We've already handled the new target and frame reattach - nothing to do here.530 return;531 }532 if (reason === 'swap') {533 // This is a local -> remote frame transtion, where534 // Page.frameDetached arrives before Target.attachedToTarget.535 // We should keep the frame in the tree, and it will be used for the new target.536 const frame = this._page._frameManager.frame(frameId);537 if (frame) this._page._frameManager.removeChildFramesRecursively(frame);538 return;539 } // Just a regular frame detach.540 this._page._frameManager.frameDetached(frameId);541 }542 _onExecutionContextCreated(contextPayload) {543 const frame = contextPayload.auxData ? this._page._frameManager.frame(contextPayload.auxData.frameId) : null;544 if (!frame || this._eventBelongsToStaleFrame(frame._id)) return;545 const delegate = new _crExecutionContext.CRExecutionContext(this._client, contextPayload);546 let worldName = null;547 if (contextPayload.auxData && !!contextPayload.auxData.isDefault) worldName = 'main';else if (contextPayload.name === UTILITY_WORLD_NAME) worldName = 'utility';548 const context = new dom.FrameExecutionContext(delegate, frame, worldName);549 context[contextDelegateSymbol] = delegate;550 if (worldName) frame._contextCreated(worldName, context);551 this._contextIdToContext.set(contextPayload.id, context);552 }553 _onExecutionContextDestroyed(executionContextId) {554 const context = this._contextIdToContext.get(executionContextId);555 if (!context) return;556 this._contextIdToContext.delete(executionContextId);557 context.frame._contextDestroyed(context);558 }559 _onExecutionContextsCleared() {560 for (const contextId of Array.from(this._contextIdToContext.keys())) this._onExecutionContextDestroyed(contextId);561 }562 _onAttachedToTarget(event) {563 const session = _crConnection.CRConnection.fromSession(this._client).session(event.sessionId);564 if (event.targetInfo.type === 'iframe') {565 // Frame id equals target id.566 const targetId = event.targetInfo.targetId;567 const frame = this._page._frameManager.frame(targetId);568 if (!frame) return; // Subtree may be already gone due to renderer/browser race.569 this._page._frameManager.removeChildFramesRecursively(frame);570 const frameSession = new FrameSession(this._crPage, session, targetId, this);571 this._crPage._sessions.set(targetId, frameSession);572 frameSession._initialize(false).catch(e => e);573 return;574 }575 if (event.targetInfo.type !== 'worker') {576 // Ideally, detaching should resume any target, but there is a bug in the backend.577 session._sendMayFail('Runtime.runIfWaitingForDebugger').then(() => {578 this._client._sendMayFail('Target.detachFromTarget', {579 sessionId: event.sessionId580 });581 });582 return;583 }584 const url = event.targetInfo.url;585 const worker = new _page.Worker(this._page, url);586 this._page._addWorker(event.sessionId, worker);587 session.once('Runtime.executionContextCreated', async event => {588 worker._createExecutionContext(new _crExecutionContext.CRExecutionContext(session, event.context));589 }); // This might fail if the target is closed before we initialize.590 session._sendMayFail('Runtime.enable');591 session._sendMayFail('Network.enable');592 session._sendMayFail('Runtime.runIfWaitingForDebugger');593 session.on('Runtime.consoleAPICalled', event => {594 const args = event.args.map(o => worker._existingExecutionContext.createHandle(o));595 this._page._addConsoleMessage(event.type, args, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));596 });597 session.on('Runtime.exceptionThrown', exception => this._page.emit(_page.Page.Events.PageError, (0, _crProtocolHelper.exceptionToError)(exception.exceptionDetails))); // TODO: attribute workers to the right frame.598 this._networkManager.instrumentNetworkEvents(session, this._page._frameManager.frame(this._targetId));599 }600 _onDetachedFromTarget(event) {601 // This might be a worker...602 this._page._removeWorker(event.sessionId); // ... or an oopif.603 const childFrameSession = this._crPage._sessions.get(event.targetId);604 if (!childFrameSession) return; // Usually, we get frameAttached in this session first and mark child as swappedIn.605 if (childFrameSession._swappedIn) {606 childFrameSession.dispose();607 return;608 } // However, sometimes we get detachedFromTarget before frameAttached.609 // In this case we don't know wheter this is a remote frame detach,610 // or just a remote -> local transition. In the latter case, frameAttached611 // is already inflight, so let's make a safe roundtrip to ensure it arrives.612 this._client.send('Page.enable').catch(e => null).then(() => {613 // Child was not swapped in - that means frameAttached did not happen and614 // this is remote detach rather than remote -> local swap.615 if (!childFrameSession._swappedIn) this._page._frameManager.frameDetached(event.targetId);616 childFrameSession.dispose();617 });618 }619 _onWindowOpen(event) {620 this._crPage._nextWindowOpenPopupFeatures.push(event.windowFeatures);621 }622 async _onConsoleAPI(event) {623 if (event.executionContextId === 0) {624 // DevTools protocol stores the last 1000 console messages. These625 // messages are always reported even for removed execution contexts. In626 // this case, they are marked with executionContextId = 0 and are627 // reported upon enabling Runtime agent.628 //629 // Ignore these messages since:630 // - there's no execution context we can use to operate with message631 // arguments632 // - these messages are reported before Playwright clients can subscribe633 // to the 'console'634 // page event.635 //636 // @see https://github.com/GoogleChrome/puppeteer/issues/3865637 return;638 }639 const context = this._contextIdToContext.get(event.executionContextId);640 if (!context) return;641 const values = event.args.map(arg => context.createHandle(arg));642 this._page._addConsoleMessage(event.type, values, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));643 }644 async _initBinding(binding) {645 await Promise.all([this._client.send('Runtime.addBinding', {646 name: binding.name647 }), this._client.send('Page.addScriptToEvaluateOnNewDocument', {648 source: binding.source649 })]);650 }651 async _onBindingCalled(event) {652 const pageOrError = await this._crPage.pageOrError();653 if (!(pageOrError instanceof Error)) {654 const context = this._contextIdToContext.get(event.executionContextId);655 if (context) await this._page._onBindingCalled(event.payload, context);656 }657 }658 _onDialog(event) {659 if (!this._page._frameManager.frame(this._targetId)) return; // Our frame/subtree may be gone already.660 this._page.emit(_page.Page.Events.Dialog, new dialog.Dialog(this._page, event.type, event.message, async (accept, promptText) => {661 await this._client.send('Page.handleJavaScriptDialog', {662 accept,663 promptText664 });665 }, event.defaultPrompt));666 }667 _handleException(exceptionDetails) {668 this._page.firePageError((0, _crProtocolHelper.exceptionToError)(exceptionDetails));669 }670 async _onTargetCrashed() {671 this._client._markAsCrashed();672 this._page._didCrash();673 }674 _onLogEntryAdded(event) {675 const {676 level,677 text,678 args,679 source,680 url,681 lineNumber682 } = event.entry;683 if (args) args.map(arg => (0, _crProtocolHelper.releaseObject)(this._client, arg.objectId));684 if (source !== 'worker') {685 const location = {686 url: url || '',687 lineNumber: lineNumber || 0,688 columnNumber: 0689 };690 this._page._addConsoleMessage(level, [], location, text);691 }692 }693 async _onFileChooserOpened(event) {694 const frame = this._page._frameManager.frame(event.frameId);695 if (!frame) return;696 let handle;697 try {698 const utilityContext = await frame._utilityContext();699 handle = await this._adoptBackendNodeId(event.backendNodeId, utilityContext);700 } catch (e) {701 // During async processing, frame/context may go away. We should not throw.702 return;703 }704 await this._page._onFileChooserOpened(handle);705 }706 _willBeginDownload() {707 const originPage = this._crPage._initializedPage;708 if (!originPage) {709 // Resume the page creation with an error. The page will automatically close right710 // after the download begins.711 this._firstNonInitialNavigationCommittedReject(new Error('Starting new page download'));712 }713 }714 _onScreencastFrame(payload) {715 this._page.throttleScreencastFrameAck(() => {716 this._client.send('Page.screencastFrameAck', {717 sessionId: payload.sessionId718 }).catch(() => {});719 });720 const buffer = Buffer.from(payload.data, 'base64');721 this._page.emit(_page.Page.Events.ScreencastFrame, {722 buffer,723 timestamp: payload.metadata.timestamp,724 width: payload.metadata.deviceWidth,725 height: payload.metadata.deviceHeight726 });727 }728 async _createVideoRecorder(screencastId, options) {729 (0, _utils.assert)(!this._screencastId);730 const ffmpegPath = _registry.registry.findExecutable('ffmpeg').executablePathOrDie(this._page._browserContext._browser.options.sdkLanguage);731 this._videoRecorder = await _videoRecorder.VideoRecorder.launch(this._crPage._page, ffmpegPath, options);732 this._screencastId = screencastId;733 }734 async _startVideoRecording(options) {735 const screencastId = this._screencastId;736 (0, _utils.assert)(screencastId);737 this._page.once(_page.Page.Events.Close, () => this._stopVideoRecording().catch(() => {}));738 const gotFirstFrame = new Promise(f => this._client.once('Page.screencastFrame', f));739 await this._startScreencast(this._videoRecorder, {740 format: 'jpeg',741 quality: 90,742 maxWidth: options.width,743 maxHeight: options.height744 }); // Wait for the first frame before reporting video to the client.745 gotFirstFrame.then(() => {746 this._crPage._browserContext._browser._videoStarted(this._crPage._browserContext, screencastId, options.outputFile, this._crPage.pageOrError());747 });748 }749 async _stopVideoRecording() {750 if (!this._screencastId) return;751 const screencastId = this._screencastId;752 this._screencastId = null;753 const recorder = this._videoRecorder;754 this._videoRecorder = null;755 await this._stopScreencast(recorder);756 await recorder.stop().catch(() => {}); // Keep the video artifact in the map utntil encoding is fully finished, if the context757 // starts closing before the video is fully written to disk it will wait for it.758 const video = this._crPage._browserContext._browser._takeVideo(screencastId);759 video === null || video === void 0 ? void 0 : video.reportFinished();760 }761 async _startScreencast(client, options = {}) {762 this._screencastClients.add(client);763 if (this._screencastClients.size === 1) await this._client.send('Page.startScreencast', options);764 }765 async _stopScreencast(client) {766 this._screencastClients.delete(client);767 if (!this._screencastClients.size) await this._client._sendMayFail('Page.stopScreencast');768 }769 async _updateExtraHTTPHeaders(initial) {770 const headers = network.mergeHeaders([this._crPage._browserContext._options.extraHTTPHeaders, this._page._state.extraHTTPHeaders]);771 if (!initial || headers.length) await this._client.send('Network.setExtraHTTPHeaders', {772 headers: (0, _utils.headersArrayToObject)(headers, false773 /* lowerCase */774 )775 });776 }777 async _updateGeolocation(initial) {778 const geolocation = this._crPage._browserContext._options.geolocation;779 if (!initial || geolocation) await this._client.send('Emulation.setGeolocationOverride', geolocation || {});780 }781 async _updateOffline(initial) {782 const offline = !!this._crPage._browserContext._options.offline;783 if (!initial || offline) await this._networkManager.setOffline(offline);784 }785 async _updateHttpCredentials(initial) {786 const credentials = this._crPage._browserContext._options.httpCredentials || null;787 if (!initial || credentials) await this._networkManager.authenticate(credentials);788 }789 async _updateViewport() {790 if (this._crPage._browserContext._browser.isClank()) return;791 (0, _utils.assert)(this._isMainFrame());792 const options = this._crPage._browserContext._options;793 const emulatedSize = this._page._state.emulatedSize;794 if (emulatedSize === null) return;795 const viewportSize = emulatedSize.viewport;...

Full Screen

Full Screen

lp-app.js

Source:lp-app.js Github

copy

Full Screen

1import { HP_HOST } from './config';2import { LitElement, html, css } from 'lit-element';3import { setPassiveTouchGestures } from '@polymer/polymer/lib/utils/settings';4import { menuIcon, Twitter, Facebook, Linkedin, Blogger, Github } from './lp-icons.js';5import './snack-bar.js';6import './search-imput-decorator';7import './speech-mic.js';8import './lp-home.js';9import { connect } from 'pwa-helpers/connect-mixin';10import { installRouter } from 'pwa-helpers/router';11import { installOfflineWatcher } from 'pwa-helpers/network';12import { installMediaQueryWatcher } from 'pwa-helpers/media-query';13import { updateMetadata, setMetaTag } from 'pwa-helpers/metadata';14import { store } from '../store.js';15import '@polymer/app-layout/app-drawer/app-drawer';16import '@polymer/app-layout/app-scroll-effects/effects/waterfall';17import '@polymer/app-layout/app-header/app-header';18import '@polymer/app-layout/app-toolbar/app-toolbar';19import {20 navigate,21 updateOffline,22 updateDrawerState,23 updateLayout,24 updateLocationURL,25} from '../actions/app';26import { Theme } from './style-theme';27import { MenuStyles } from './style-menu';28import { ButtonStyle } from './style-button';29import { SearchIcon } from './lp-icons';30class App extends connect(store)(LitElement) {31 static get styles() {32 return [33 Theme,34 MenuStyles,35 ButtonStyle,36 SearchIcon,37 css`38 /*--------------------------------------------------------------39 # Accessibility40 --------------------------------------------------------------*/41 /* Text meant only for screen readers. */42 .screen-reader-text {43 clip: rect(1px, 1px, 1px, 1px);44 position: absolute !important;45 height: 1px;46 width: 1px;47 overflow: hidden;48 word-wrap: normal !important;49 /* Many screen reader and browser combinations announce broken words as they would appear visually. */50 }51 .screen-reader-text:focus {52 background-color: #f1f1f1;53 border-radius: 3px;54 box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);55 clip: auto !important;56 color: #21759b;57 display: block;58 font-size: 14px;59 font-size: 0.875rem;60 font-weight: bold;61 height: auto;62 left: 5px;63 line-height: normal;64 padding: 15px 23px 14px;65 text-decoration: none;66 top: 5px;67 width: auto;68 z-index: 100000;69 /* Above WP toolbar. */70 }71 /* Do not show the outline on the skip link target. */72 #primary[tabindex='-1']:focus {73 outline: 0;74 }75 [hidden] {76 display: none !important;77 }78 app-header {79 position: fixed;80 top: 0;81 left: 0;82 z-index: 200;83 width: 100%;84 text-align: left;85 background-color: var(--app-header-background-color);86 color: var(--app-header-text-color);87 border-bottom: 1px solid var(--app-primary-border-color);88 }89 nav {90 height: 46px;91 }92 .masthead {93 background-color: var(--app-primary-background-color);94 padding: 12px 8px;95 height: inherit;96 align-items: center;97 }98 .title {99 margin-left: 0px;100 font-weight: 300;101 color: var(--app-secondary-color);102 }103 .paper-font-body2 {104 font-size: 14px;105 transform: uppercase;106 }107 .cta-header {108 background: var(--app-secondary-background-color);109 font-size: 1.2rem;110 margin-right: 24px;111 padding: 0px 10px 0px 10px;112 border: solid 1px var(--app-form-border-color);113 -webkit-border-radius: 10em;114 -moz-border-radius: 10em;115 border-radius: 10em;116 }117 .cta-header:focus-within {118 background-color: var(--app-reverse-text-color);119 -webkit-box-shadow: 0 0 5px rgba(28, 64, 26, 0.9);120 -moz-box-shadow: 0 0 5px rgba(28, 64, 26, 0.9);121 box-shadow: 0 0 5px rgba(28, 64, 26, 0.9);122 }123 .search-btn {124 background: var(--app-reverse-text-color);125 border: 1px solid var(--app-primary-icon-color);126 fill: var(--app-primary-icon-color);127 cursor: pointer;128 width: 34px;129 height: 33px;130 position: absolute;131 top: 24px;132 padding: 4px 5px 4px 5px;133 }134 .search-btn:hover {135 background: var(--app-primary-icon-color);136 fill: var(--app-reverse-text-color);137 }138 input[type='search'] {139 background: var(--app-secondary-background-color);140 padding: 8px 8px 8px 8px;141 width: 220px;142 margin-top: 14px;143 margin-bottom: 14px;144 border-top: 1px solid var(--app-form-border-color);145 border-right: 0px solid var(--app-form-border-color);146 border-left: 1px solid var(--app-form-border-color);147 border-bottom: 1px solid var(--app-form-border-color);148 }149 input[type='search']:focus {150 background-color: var(--app-reverse-text-color);151 }152 input:-moz-placeholder,153 input::-webkit-input-placeholder {154 color: var(--app-footer-secondary-background-color);155 }156 input:-moz-placeholder:focus,157 input::-webkit-input-placeholder:focus {158 color: var(--app-form-text-color);159 }160 .toolbar-top {161 background-color: var(--app-header-background-color);162 }163 [main-title] {164 font-family: 'Roboto';165 text-transform: lowercase;166 font-size: 24px;167 /* 168 In the narrow layout, the toolbar is offset by the width of the169 drawer button, and the text looks not centered. Add a padding to170 match that button 171 */172 padding-right: 44px;173 }174 .sub-tagline {175 margin-left: 5px;176 }177 .toolbar-list {178 display: none;179 }180 .toolbar-list > a {181 display: inline-block;182 color: var(--app-header-text-color);183 text-decoration: none;184 line-height: 30px;185 padding: 0px 18px;186 }187 .toolbar-list > a[selected] {188 color: var(--app-header-selected-color);189 border-bottom: 4px solid var(--app-header-selected-color);190 }191 /* 192 We need to make sure when drawer is open193 it covers our app header. Otherwise there's194 menu button that is disabled 195 */196 #drawer {197 z-index: 200;198 }199 #drawer app-toolbar {200 border-bottom: 1px solid var(--app-primary-border-color);201 margin-bottom: 5px;202 background-color: var(--app-primary-color);203 color: var(--app-reverse-text-color);204 }205 .drawer-list {206 box-sizing: border-box;207 width: 100%;208 height: 100%;209 padding: 10px 24px;210 background: var(--app-drawer-background-color);211 position: relative;212 text-align: left;213 overflow-y: auto;214 }215 .drawer-list > a {216 display: block;217 text-decoration: none;218 font: 400 16px/24px Roboto, sans-serif;219 color: var(--app-drawer-text-color);220 letter-spacing: 0.25px;221 padding: 0.6rem 8px 0.6rem 0px;222 }223 .drawer-list > a[selected] {224 color: var(--app-drawer-selected-color);225 }226 .main-content {227 padding-top: 20px;228 min-height: 100vh;229 }230 .page {231 display: none;232 }233 .page[active] {234 display: block;235 }236 .footer-linkboxes-all-backup,237 .footer-linkbox-cloud {238 background-color: var(--app-footer-primary-background-color);239 }240 .footer-linkboxes > nav::before {241 background: var(--app-footer-primary-background-color);242 border-bottom: solid 1px var(--app-form-border-color);243 color: var(--app-footer-primary-background-color);244 content: 'Logical Phase';245 display: block;246 height: 73px;247 padding: 24px;248 }249 *,250 *:before,251 *:after {252 -webkit-box-sizing: inherit;253 box-sizing: inherit;254 }255 .nav {256 font-size: 13px;257 }258 .site-name {259 display: none;260 }261 .utility-footer-nav {262 color: var(--app-reverse-text-color);263 overflow: auto;264 padding: 10px 24px;265 }266 .full-site-width,267 .toast-fill {268 margin: 0 auto;269 color: var(--app-footer-text-color);270 }271 .footer-linkboxes-all-backup,272 .footer-linkbox-cloud {273 background-color: var(--app-footer-primary-background-color);274 }275 .footer-linkboxes {276 background: #263238;277 font: 14px/16px Roboto, sans-serif;278 }279 .utility-footer {280 background: var(--app-footer-secondary-background-color);281 color: var(--app-footer-text-color);282 text-align: center;283 }284 .utility-footer-nav-left {285 display: inline-block;286 padding-right: 20px;287 }288 .utility-footer-nav-right {289 display: inline-block;290 }291 .utility-footer-link + .utility-footer-link::before {292 content: '|';293 padding-left: 6px;294 padding-right: 8px;295 }296 footer nav {297 height: inherit;298 }299 .utility-footer-link {300 color: var(--app-reverse-text-color);301 font-size: 14px;302 font-weight: 400;303 text-decoration: none;304 }305 .utility-footer-links,306 .utility-footer-newsletter-signup-text {307 font-weight: 500;308 margin-right: 16px;309 }310 .brand-site-logo {311 display: block;312 height: auto;313 width: 141px;314 text-align: left;315 margin-left: 12px;316 }317 img {318 border: 0;319 max-width: 100%;320 }321 /* 322 Wide layout: when the viewport width is bigger than 460px, layout323 changes to a wide layout. 324 */325 @media (min-width: 460px) {326 #dropdownMenuButton {327 margin-right: 3px;328 padding-top: 13px;329 }330 .toolbar-list {331 display: block;332 }333 .cta-header {334 background: var(--app-secondary-background-color);335 font-size: 1.1rem;336 margin-right: 24px;337 border: solid 1px var(--app-form-border-color);338 -webkit-border-radius: 4px;339 -moz-border-radius: 4px;340 border-radius: 4px;341 }342 .cta-header:focus-within {343 border: none;344 }345 .small-print .social-icon {346 padding-left: 0px;347 }348 .get-social {349 font-size: 16px;350 font-weight: 400;351 }352 a.social-icon {353 margin-right: 0px;354 margin-left: 8px;355 }356 .social-icon svg {357 border:1px solid var(--app-primary-text-thin-color);358 border-radius: 5px;359 padding: 3px;360 margin-top: 8px;361 }362 .social-icon {363 fill: var(--app-primary-text-thin-color);364 padding-left: 0;365 cursor: pointer;366 }367 .gplus-icon:hover {368 fill: #db4437;369 }370 .blogger-icon:hover {371 fill: #fb8f3d;372 }373 .twitter-icon:hover {374 fill: #1da1f2;375 }376 .facebook-icon:hover {377 fill: #3b5998;378 }379 .linkedin-icon:hover {380 fill: #007bb5;381 }382 input[type='search']::placeholder {383 font-size: 14px;384 }385 input[type='search'] {386 background: var(--app-secondary-background-color);387 width: 170px;388 font-size: 1rem;389 padding: 0px 0px 0px 8px;390 margin-top: 0px;391 margin-bottom: 0px;392 border: none;393 -webkit-transition: all 0.5s;394 -moz-transition: all 0.5s;395 transition: all 0.5s;396 }397 input[type='search']:focus {398 width: 380px;399 background-color: var(--app-reverse-text-color);400 }401 lp-input-decorator {402 max-width: 460px;403 transform: translate3d(0, 0, 0);404 }405 lp-input-decorator[top] {406 transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);407 transform: translate3d(0, 0, 0);408 }409 .masthead {410 padding: 5px 8px 5px 36px;411 }412 .brand-site-logo {413 display: block;414 height: auto;415 width: 168px;416 margin-left: 0px;417 }418 .menu-btn {419 display: none;420 }421 .toolbar-list > a {422 padding: 0px 18px;423 }424 ul.nav-right {425 width: 50%;426 }427 .main-content {428 padding-top: 55px;429 }430 nav.full-site-width {431 background-color: #212121 !important;432 }433 .utility-footer-nav-left {434 float: left;435 }436 .utility-footer-nav-right {437 float: right;438 }439 .footer-linkboxes > nav::before {440 background-color: var(--app-footer-primary-background-color) !important;441 color: var(--app-secondary-background-color);442 content: 'Logical Phase';443 display: block;444 min-height: 73px;445 padding: 24px;446 }447 /* The drawer button isn't shown in the wide layout, so we don't448 need to offset the title */449 [main-title] {450 padding-right: 0px;451 }452 html[dir='rtl'] .microphone-icon {453 left: 0;454 right: auto;455 }456 #realbox-input-wrapper > :-webkit-any(.google-g-icon, .microphone-icon, .search-icon) {457 z-index: 3;458 }459 }460 `,461 ];462 }463 render() {464 const {465 _page,466 _offline,467 _drawerOpened,468 _snackbarOpened,469 _searchTerms,470 } = this;471 const hideInput = !_page;472 // True to make the search input aligns at the top inside the header instead of inside the main content.473 const inputAtTop = 'ontouchstart' in window || !_page;474 const searchTerms = _page ? '' : _searchTerms;475 const appTitle = "Digital Experience Solutions by Logical Phase";476 const appShortTitle = "Logical Phase";477 updateMetadata({478 title: `Digital Experience Solutions by Logical Phase`,479 description: `Combining powerful cloud technologies that keep you ahead of the competition`,480 image: `https://storage.googleapis.com/logicalphase.com/assets/9a6ed0c3-bg-homepage-container.jpg`,481 });482 setMetaTag('name', 'twitter:card', 'photo');483 setMetaTag('name', 'twitter:url', 'https://logicalphase.com/');484 return html`485 <!-- Header -->486 <header class="header-wrapper">487 <app-header-layout id="appheaderlayout" has-scrolling-region>488 <app-header slot="header" condenses reveals effects="waterfall">489 <app-toolbar class="masthead">490 <a href="/">491 <img492 rel="dns-prefetch"493 class="brand-site-logo"494 src="/images/logicalphase-logo-204x36.svg"495 alt="${appTitle} logo"496 />497 </a>498 <div class="title" main-title>499 <span class="site-name">${appTitle}</span>500 </div>501 <div class="cta-header toolbar-list">502 <lp-input-decorator ?top="${inputAtTop}" ?hidden="${hideInput}">503 <input504 slot="input"505 id="input"506 aria-label="Search Content"507 type="search"508 placeholder="Enter search term"509 value="${decodeURI(searchTerms)}"510 @change="${e => store.dispatch(updateLocationURL(`/search/${e.target.value}`))}"511 />512 <speech-mic513 slot="button"514 continuous515 interimResults516 @result="${e => this._micResult(e)}"517 ></speech-mic>518 </lp-input-decorator>519 </div>520 <button521 class="menu-btn"522 title="Menu"523 @click="${() => store.dispatch(updateDrawerState(true))}"524 >525 ${menuIcon}526 </button>527 </app-toolbar>528 <app-toolbar class="desktop-menu toolbar-list" sticky>529 <nav role="navigation" aria-label="Header Navigation Menu">530 <div class="main-navigation">531 <a ?selected="${_page === 'home'}" href="/">Home</a>532 <a ?selected="${_page === 'about'}" href="/about">About</a>533 <button534 id="dropdownMenuButton"535 class="toolbar-platform-chooser__button"536 role="menu"537 aria-haspopup="true"538 aria-owns="dropdownListElement"539 aria-controls="dropdownListElement"540 @click="${this._toggleDropdownMenu}"541 >542 <span class="toolbar-platform-chooser__label">Solutions</span>543 <svg544 class="triangle dropdown__arrow closed"545 width="24"546 height="24"547 viewBox="0 0 24 24"548 fill="none"549 >550 <title>Open drop down menu</title>551 <path d="M7 10l5 5 5-5z"></path>552 </svg>553 </button>554 <a ?selected="${_page === 'blog'}" href="/blog">Blog</a>555 <a ?selected="${_page === 'contact'}" href="/contact">Contact</a>556 <div class="slide-icons slide-left login-nav-item">557 <span class="get-social">Get social</span>558 <a559 class="social-icon twitter-icon"560 href="https://twitter.com/logicalphase/"561 >${Twitter}</a562 >563 <a564 class="social-icon linkedin-icon"565 href="https://www.linkedin.com/in/john-t-teague/"566 >${Linkedin}</a567 >568 <a569 class="social-icon github-icon"570 href="https://github.com/logicalphase"571 >${Github}</a572 >573 </div>574 </div>575 <div576 id="dropdownListElement"577 class="main-navigation dropdown-menu hide"578 data-target="slide-content"579 role="group"580 aria-labelledby="dropdownMenuButton"581 aria-hidden="true"582 >583 <a584 class="dropdown-item submenu"585 ?selected="${_page === 'pagespeed'}"586 href="/pagespeed"587 role="menuitem"588 >Site Performance</a589 >590 <a591 class="dropdown-item submenu"592 ?selected="${_page === 'security'}"593 href="/security"594 role="menuitem"595 >Security Services</a596 >597 <a class="submenu" 598 ?selected="${_page === 'hosting'}" 599 href="/hosting"600 role="menuitem"601 >GCP Hosting Solutions</a602 >603 <a 604 class="submenu" 605 ?selected="${_page === 'design'}" 606 href="/design"607 role="menuitem"608 >Progressive Web Apps</a609 >610 <a611 class="dropdown-item submenu"612 ?selected="${_page === 'migration'}"613 href="/migration"614 role="menuitem"615 >Site Migrations</a616 >617 </div>618 </nav>619 </app-toolbar>620 </app-header>621 </app-header-layout>622 </header>623 <!-- Drawer content -->624 <app-drawer625 id="drawer"626 .opened="${_drawerOpened}"627 @opened-changed="${e => store.dispatch(updateDrawerState(e.target.opened))}"628 swipe-open629 >630 <app-toolbar>631 ${appShortTitle}632 </app-toolbar>633 <nav class="drawer-list">634 <div class="search-wrapper">635 <form636 class="header-search-drawer"637 name="toolbar-search-drawer"638 action="/search/wordpress"639 >640 <input641 class="search-field-drawer"642 type="search"643 aria-label="Search box"644 placeholder="Search..."645 value="" 646 tabindex="-1"647 />648 <button649 class="search-btn"650 title="Search"651 @click="${() => this._getValueFromSearchFieldDrawer()}"652 tabindex="-1"653 >654 ${SearchIcon}655 </button>656 </form>657 </div>658 <a ?selected="${_page === 'home'}" href="/">Home</a>659 <a ?selected="${_page === 'about'}" href="/about">About</a>660 <a class="submenu" ?selected="${_page === 'pagespeed'}" href="/pagespeed">Site Performance</a>661 <a class="submenu" ?selected="${_page === 'security'}" href="/security">Security Services</a>662 <a class="submenu" ?selected="${_page === 'hosting'}" href="/hosting">Cloud Hosting</a>663 <a class="submenu" ?selected="${_page === 'design'}" href="/design">Progressive Web Apps</a>664 <a class="submenu" ?selected="${_page === 'migration'}" href="/migration">Site Migrations</a>665 <a ?selected="${_page === 'blog'}" href="/blog">Logical Blog</a>666 <a ?selected="${_page === 'contact'}" href="/contact">Contact Us</a>667 <a ?selected="${_page === 'support'}" href="/support">Client Support</a>668 <a ?selected="${_page === 'privacy'}" href="/privacy">Privacy</a>669 <a ?selected="${_page === 'terms'}" href="/terms">Terms of Service</a>670 </nav>671 </app-drawer>672 <!-- Main content -->673 <main class="main-content">674 <lp-home class="page" ?active="${_page === 'home'}"></lp-home>675 <lp-article class="page" ?active="${_page === 'article'}"></lp-article>676 <lp-about class="page" ?active="${_page === 'about'}"></lp-about>677 <lp-blog class="page" ?active="${_page === 'blog'}"></lp-blog>678 <lp-contact class="page" ?active="${_page === 'contact'}"></lp-contact>679 <lp-category class="page" ?active="${_page === 'category'}"></lp-category>680 <lp-design class="page" ?active="${_page === 'design'}"></lp-design>681 <lp-hosting class="page" ?active="${_page === 'hosting'}"></lp-hosting>682 <lp-migration class="page" ?active="${_page === 'migration'}"></lp-migration>683 <lp-pagespeed class="page" ?active="${_page === 'pagespeed'}"></lp-pagespeed>684 <lp-privacy class="page" ?active="${_page === 'privacy'}"></lp-privacy>685 <lp-search class="page" ?active="${_page === 'search'}"></lp-search>686 <lp-security class="page" ?active="${_page === 'security'}"></lp-security>687 <lp-support class="page" ?active="${_page === 'support'}"></lp-support>688 <lp-terms class="page" ?active="${_page === 'terms'}"></lp-terms>689 <lp-view404 class="page" ?active="${_page === '404'}"></lp-view404>690 </main>691 <!-- Footer content -->692 <footer title="footer-links" class="footer-linkboxes nocontent footer-linkboxes-all-backup">693 <nav aria-label="footer" class="full-site-width"></nav>694 <div title="footer-navigation" class="utility-footer">695 <nav aria-label="policy" class="utility-footer-nav nav full-site-width">696 <div class="utility-footer-nav-left">697 <span class="footer-links">698 <a class="utility-footer-link gc-analytics-event" href="/terms">Site Terms</a>699 <a class="utility-footer-link gc-analytics-event" href="/privacy">Privacy</a>700 </span>701 </div>702 <div class="utility-footer-nav-right">703 <span class="footer-links">704 <span class="utility-footer-link gc-analytics-event">Copyright © 2019 Logical Phase. All Rights Reserved</span>705 </span>706 </div>707 </nav>708 </div>709 </footer>710 <snack-bar ?active="${_snackbarOpened}">711 You are currently ${_offline ? 'offline' : 'online'}.</snack-bar712 >713 `;714 }715 static get properties() {716 return {717 appTitle: {718 type: String,719 },720 appShortTitle: {721 type: String,722 },723 _query: {724 type: String,725 },726 _categoryId: {727 type: String,728 },729 _page: {730 type: String,731 },732 _lazyResourcesLoaded: {733 type: Boolean,734 },735 _lastVisitedListPage: {736 type: Boolean,737 },738 _offline: {739 type: Boolean,740 },741 _drawerOpened: {742 type: Boolean,743 },744 _snackbarOpened: {745 type: Boolean,746 },747 _updateOffline: {748 type: Boolean,749 },750 _data: {751 type: Object,752 },753 _item: {754 type: Object,755 },756 _articleSlug: {757 type: String,758 },759 dropdownList: {760 type: String,761 },762 searchFieldValue: {763 type: String,764 },765 searchTerms: {766 type: Object,767 },768 _searchAction: {769 type: Object,770 },771 };772 }773 constructor() {774 super();775 // To force all event listeners for gestures to be passive.776 // See https://www.polymer-project.org/3.0/docs/devguide/settings#setting-passive-touch-gestures777 setPassiveTouchGestures(true);778 }779 firstUpdated() {780 installRouter(location => store.dispatch(navigate(location)));781 installOfflineWatcher(offline => store.dispatch(updateOffline(offline)));782 installMediaQueryWatcher(`(min-width: 648px) and (min-height: 648px)`, matches =>783 store.dispatch(updateLayout(matches)),784 );785 this.removeAttribute('unresolved');786 this._input = this.shadowRoot.getElementById('input');787 }788 updated(changedProps) {789 if (changedProps.has('_page')) {790 const pageTitle = this.appTitle + ' - ' + this._page;791 updateMetadata({792 title: pageTitle,793 description: pageTitle,794 // This object also takes an image property, that points to an img src.795 });796 // Maybe move this into a store, but for now I need a quick and dirty way797 // to make sure the dropdown menu element closes after a menu selection798 // and to properly update aria attributes.799 this._hideDropdownButtonBlur();800 window.scrollTo(0, 0);801 }802 }803 _toggleDropdownMenu(e) {804 const dropdownButton = this.shadowRoot.getElementById('dropdownMenuButton');805 const dropdownList = this.shadowRoot.getElementById('dropdownListElement');806 const dropdownArrow = this.shadowRoot.querySelector('.dropdown__arrow');807 if (dropdownList.classList.contains('hide')) {808 dropdownList.classList.replace('hide', 'show');809 dropdownArrow.classList.replace('closed', 'open');810 dropdownButton.setAttribute('aria-expanded', 'true');811 dropdownList.setAttribute('aria-hidden', 'false');812 console.log(dropdownList.classList);813 } else {814 dropdownList.classList.replace('show', 'hide');815 dropdownArrow.classList.replace('open', 'closed');816 dropdownButton.setAttribute('aria-expanded', 'false');817 dropdownList.setAttribute('aria-hidden', 'true');818 console.log(dropdownList.classList);819 }820 }821 _hideDropdownButtonBlur(e) {822 const dropdownButton = this.shadowRoot.getElementById('dropdownMenuButton');823 const dropdownList = this.shadowRoot.getElementById('dropdownListElement');824 const dropdownArrow = this.shadowRoot.querySelector('.dropdown__arrow');825 dropdownList.classList.replace('show', 'hide');826 dropdownArrow.classList.replace('open', 'closed');827 dropdownButton.setAttribute('aria-expanded', 'false');828 dropdownList.setAttribute('aria-hidden', 'true');829 }830 // To get our drawer search to work we need to get the value of the search field831 // and set the action attribute of our form action. We should add a condition832 // so if the search form is empty, return a message we need an actual search term.833 _getValueFromSearchFieldDrawer(e) {834 const searchTermsDrawer = this.shadowRoot.querySelector('.search-field-drawer').value;835 const searchActionDrawer = (this.shadowRoot.querySelector('.header-search-drawer').action =836 '/search/' + searchTermsDrawer);837 }838 stateChanged(state) {839 this.appTitle = state.app.appTitle;840 this._page = state.app.page;841 this._lastVisitedListPage = state.app.lastVisitedListPage;842 this._offline = state.app.offline;843 this._snackbarOpened = state.app.snackbarOpened;844 this._drawerOpened = state.app.drawerOpened;845 this._data = state.article && state.article.data;846 this._item = state.article && state.article.item;847 this._query = state.articles && state.articles.query;848 this._categoryId = state.categories && state.categories.categoryId;849 this._articleSlug = state.article && state.article.slug;850 this._searchTerms = state.search_results && state.search_results.searchTerms;851 this._searchAction = state.search_results && state.search_results._searchAction;852 }853 _micResult(e) {854 const d = e.detail;855 const value = d.completeTranscript;856 this._input.value = value;857 if (d.isFinal) {858 store.dispatch(updateLocationURL(`/search/${value}`));859 }860 }861}...

Full Screen

Full Screen

PresenceStore.js

Source:PresenceStore.js Github

copy

Full Screen

...33 user.lastEventTimestamp = eventTimestamp;34 if (status === 'on') {35 _updateOnline(user);36 } else {37 _updateOffline(user);38 }39}40function _updateOnline(user) {41 user.status = 'on';42 clearTimeout(user.timeoutId); // In case a setTimeout is running43 user.timeoutId = null;44}45function _updateOffline(user) {46 if (user.status !== 'on' || user.timeoutId) return;47 user.timeoutId = setTimeout(function() { // To prevent blinking on auto-reconnection48 delete _state.users[user.userId];49 PresenceStore.emitEvent(); // TODO: Couldn't find a better way50 }, 5000);51}52var PresenceStore = assign({}, EventEmitter.prototype, {53 emitEvent: function() {54 this.emit(CHANGE_EVENT);55 },56 addChangeListener: function(callback) {57 this.on(CHANGE_EVENT, callback);58 },59 removeChangeListener: function(callback) {...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext();5 const page = await context.newPage();6 await page._updateOffline(true);7 await page.reload();8 await page.screenshot({ path: 'test.png' });9 await browser.close();10})();11const { chromium } = require('playwright');12(async () => {13 const browser = await chromium.launch({ headless: false });14 const context = await browser.newContext();15 const page = await context.newPage();16 await page._updateOffline(true);17 await page.reload();18 await page.screenshot({ path: 'test.png' });19 await browser.close();20})();21const { chromium } = require('playwright');22(async () => {23 const browser = await chromium.launch({ headless: false });24 const context = await browser.newContext();25 const page = await context.newPage();26 await page._updateOffline(true);27 await page.reload();28 await page.screenshot({ path: 'test.png' });29 await browser.close();30})();31const { chromium } = require('playwright');32(async () => {33 const browser = await chromium.launch({ headless: false });34 const context = await browser.newContext();35 const page = await context.newPage();36 await page._updateOffline(true);37 await page.reload();38 await page.screenshot({ path: 'test.png' });39 await browser.close();40})();41const { chromium } = require('playwright');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2const fs = require('fs');3(async () => {4 const browser = await chromium.launch({headless: false});5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.evaluate(() => {8 const offline = true;9 const updateOffline = window.__playwright__._updateOffline;10 updateOffline(offline);11 });12 await page.screenshot({path: 'offline.png'});13 await browser.close();14})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2const path = require('path');3const fs = require('fs');4(async () => {5 for (const browserType of ['chromium']) {6 const browser = await playwright[browserType].launch();7 const context = await browser.newContext();8 const page = await context.newPage();9 const offlinePath = path.join(__dirname, 'offline.html');10 const offlineContent = fs.readFileSync(offlinePath, 'utf8');11 await page._updateOffline(offlineContent);12 await page.screenshot({ path: `example-${browserType}.png` });13 await browser.close();14 }15})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { _updateOffline } = require('playwright/lib/server/browserType');2_updateOffline(false);3const { _updateOffline } = require('playwright/lib/server/browserType');4_updateOffline(false);5const { _updateOffline } = require('playwright/lib/server/browserType');6_updateOffline(false);7const { _updateOffline } = require('playwright/lib/server/browserType');8_updateOffline(false);9const { _updateOffline } = require('playwright/lib/server/browserType');10_updateOffline(false);11const { _updateOffline } = require('playwright/lib/server/browserType');12_updateOffline(false);13const { _updateOffline } = require('playwright/lib/server/browserType');14_updateOffline(false);15const { _updateOffline } = require('playwright/lib/server/browserType');16_updateOffline(false);17const { _updateOffline } = require('playwright/lib/server/browserType');18_updateOffline(false);19const { _updateOffline } = require('playwright/lib/server/browserType');20_updateOffline(false);21const { _updateOffline } = require('playwright/lib/server/browserType');22_updateOffline(false);23const { _updateOffline } = require('playwright/lib/server/browserType');24_updateOffline(false);25const { _updateOffline } = require('playwright/lib/server/browserType');26_updateOffline(false);27const { _updateOffline } = require('playwright/lib/server/browserType');28_updateOffline(false);29const { _updateOffline } = require('playwright/lib/server/browserType');30_updateOffline(false);

Full Screen

Using AI Code Generation

copy

Full Screen

1const { _updateOffline } = require('playwright-core/lib/server/browserContext');2const { chromium } = require('playwright-core');3const context = await chromium.launch().newContext();4await _updateOffline(context, false);5await context.close();6const { _updateOffline } = require('playwright-core/lib/server/browserContext');7const { chromium } = require('playwright-core');8const context = await chromium.launch().newContext();9await _updateOffline(context, false);10await context.close();11const { _updateOffline } = require('playwright-core/lib/server/browserContext');12const { chromium } = require('playwright-core');13const context = await chromium.launch().newContext();14await _updateOffline(context, false);15await context.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright');2const { BrowserType } = require('playwright/types/types');3const { BrowserContext } = require('playwright/types/types');4const { Browser } = require('playwright/types/types');5const { Page } = require('playwright/types/types');6const { BrowserContextOptions } = require('playwright/types/types');7const { LaunchOptions } = require('playwright/types/types');8const { ChromiumBrowser } = require('playwright/types/types');9const { ChromiumBrowserContext } = require('playwright/types/types');10const { ChromiumPage } = require('playwright/types/types');11const browserType = Playwright['chromium'];12const browser = browserType['launch']({headless: false});13const context = browser['newContext']();14const page = context['newPage']();15const chromiumBrowser = browser;16const chromiumBrowserContext = context;17const chromiumPage = page;18chromiumBrowserContext['_updateOffline'](true);19chromiumPage['_updateOffline'](true);20const chromiumBrowser = browser;21const chromiumBrowserContext = context;22const chromiumPage = page;23chromiumBrowserContext['_updateOffline'](false);24chromiumPage['_updateOffline'](false);25const chromiumBrowser = browser;26const chromiumBrowserContext = context;27const chromiumPage = page;28chromiumBrowserContext['_updateOffline'](true);29chromiumPage['_updateOffline'](true);30chromiumPage['_updateOffline'](false);31const chromiumBrowser = browser;32const chromiumBrowserContext = context;33const chromiumPage = page;34chromiumBrowserContext['_updateOffline'](false);35chromiumPage['_updateOffline'](false);36chromiumPage['_updateOffline'](true);37const chromiumBrowser = browser;38const chromiumBrowserContext = context;39const chromiumPage = page;40chromiumBrowserContext['_updateOffline'](true);41chromiumPage['_updateOffline'](true);42chromiumPage['_updateOffline'](false);43const chromiumBrowser = browser;44const chromiumBrowserContext = context;45const chromiumPage = page;

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright');2const playwright = new Playwright();3const browser = playwright.chromium.launch();4const context = browser.newContext();5const page = context.newPage();6await page._updateOffline(true);7await page._updateOffline(false);8await page.close();9await context.close();10await browser.close();11await playwright.stop();

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