mirror of
https://github.com/cypress-io/cypress.git
synced 2026-03-06 06:49:18 -06:00
feat(webkit): fix multidomain driver tests in WebKit (#23442)
* Initial async changes * Small fixes and test updates. * updating tests * Fixes for cookie login tests * remove the onlys * Most tests passing * Fix driver tests? * fix firefox test? * fix unit tests * fix tests?? * a better check * fix integration tests * minor cleanup * Comment out tyler fix for 10.0 origin issue * also fix integration tests * remove fixmes * Adding Retries for cookie actions. May break other error tests. * Address (some) PR comments * factor console logging out of run.ts * fix print-run * minimize diff * chore(server): convert browsers/index to typescript * fix tests * update stubbed tests * convert electron.js to .ts * Suggestions from code review * Clean up new type errors * electron.connectToExisting can be sync * more type errors for the type god * Suggestions from code review * refactor: move more of video capture into browser automations * unit tests * refactor: move videoCapture to browsers * fix snapshots * update to warn about cross origin command AUT in assertions * Fix type errors * fix multi-spec videos? * webkit video recording works! * webkit system tests * skip system-tests that won't be fixed in this PR ~60 tests skipped out of ~99: * ~6 skipped due to needing multidomain support * ~8 skipped due to missing before:browser:launch support * ~22 skipped due to broken stack traces * fix single-tab mode * cleanup/api renames * fix more tests * minimize diff, fix ff * fix unit tests * fix tests * cleanup * Move document.cookie patch to injection * enable ci job * fix up/add request events to webkit automation * update undefined message * doesn't need an underscore * Adding iframe patching. * forward errors prior to attaching * Add error message when using visit to visit a cross origin site with the onLoad or onBeforeLoad options. * Attempt to fix test errors. * more fixes, but not all * use the origin policy * Fix types * more fixes * consider chromeWebSecurity when checking if you can communicate with the AUT * firefox * prevent hangs if before unload happens after on load. * Fix some ToDos * code cleanup * remove quotes * Code review changes * more cr changes * fix tests possibly * Updating cy.origin websocket for webkit connection error * for realz this time * temp fix for before:unload/load issue * roll back change * Fix some flake * temporarily comment out autWindow.Error patch * updating cookies to match develop * update circle.yml * commenting out driver-integration-tests-webkit-experimentalSessionAndOrigin * revert cookie test change * revert cross origin change * Fix clear cookie problem * Try it again * test cy.origin in webkit * Skip origin tests when running in webkit * missed one * attempt to revert web_security changes * enable sessions on webkit * maybe this fixes system tests?? * Update web_security_spec.js * Update web_security_spec.js * file cleanup * Unify socket creation logic * Address PR Comments Co-authored-by: mjhenkes <mjhenkes@gmail.com> Co-authored-by: Matt Schile <mschile@cypress.io>
This commit is contained in:
@@ -47,6 +47,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters
|
||||
when:
|
||||
or:
|
||||
- equal: [ develop, << pipeline.git.branch >> ]
|
||||
- equal: [ 'webkit-multidomain', << pipeline.git.branch >> ]
|
||||
- equal: [ 'issue-23843_electron_21_upgrade', << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: "-release$"
|
||||
@@ -1856,7 +1857,7 @@ jobs:
|
||||
name: Build
|
||||
command: yarn workspace @cypress/mount-utils build
|
||||
- store-npm-logs
|
||||
|
||||
|
||||
npm-xpath:
|
||||
<<: *defaults
|
||||
resource_class: small
|
||||
@@ -2437,11 +2438,10 @@ linux-x64-workflow: &linux-x64-workflow
|
||||
context: test-runner:cypress-record-key
|
||||
requires:
|
||||
- build
|
||||
# TODO: Implement WebKit network automation to fix the majority of these tests before re-enabling
|
||||
# - driver-integration-tests-webkit-experimentalSessionAndOrigin:
|
||||
# context: test-runner:cypress-record-key
|
||||
# requires:
|
||||
# - build
|
||||
- driver-integration-tests-webkit-experimentalSessionAndOrigin:
|
||||
context: test-runner:cypress-record-key
|
||||
requires:
|
||||
- build
|
||||
- run-frontend-shared-component-tests-chrome:
|
||||
context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy]
|
||||
percy: true
|
||||
|
||||
@@ -22,7 +22,7 @@ import { getRunnerElement, empty } from './utils'
|
||||
import { IframeModel } from './iframe-model'
|
||||
import { AutIframe } from './aut-iframe'
|
||||
import { EventManager } from './event-manager'
|
||||
import { client } from '@packages/socket/lib/browser'
|
||||
import { createWebsocket as createWebsocketIo } from '@packages/socket/lib/browser'
|
||||
import { decodeBase64Unicode } from '@packages/frontend-shared/src/utils/base64'
|
||||
import type { AutomationElementId } from '@packages/types/src'
|
||||
import { useSnapshotStore } from './snapshot-store'
|
||||
@@ -31,11 +31,7 @@ import { useStudioStore } from '../store/studio-store'
|
||||
let _eventManager: EventManager | undefined
|
||||
|
||||
export function createWebsocket (config: Cypress.Config) {
|
||||
const ws = client({
|
||||
path: config.socketIoRoute,
|
||||
// TODO(webkit): the websocket socket.io transport is busted in WebKit, need polling
|
||||
transports: config.browser.family === 'webkit' ? ['polling'] : ['websocket'],
|
||||
})
|
||||
const ws = createWebsocketIo({ path: config.socketIoRoute, browserFamily: config.browser.family })
|
||||
|
||||
ws.on('connect', () => {
|
||||
ws.emit('runner:connected')
|
||||
|
||||
@@ -2,6 +2,25 @@ const { assertLogLength } = require('../../support/utils')
|
||||
const { stripIndent } = require('common-tags')
|
||||
const { Promise } = Cypress
|
||||
|
||||
describe('src/cy/commands/cookies - no stub', () => {
|
||||
it('clears all cookies', () => {
|
||||
cy.setCookie('foo', 'bar')
|
||||
cy.getCookies().should('have.length', 1)
|
||||
cy.clearCookies()
|
||||
cy.getCookies().should('have.length', 0)
|
||||
})
|
||||
|
||||
it('clears a single cookie', () => {
|
||||
cy.setCookie('foo', 'bar')
|
||||
cy.setCookie('key', 'val')
|
||||
cy.getCookies().should('have.length', 2)
|
||||
cy.clearCookie('foo')
|
||||
cy.getCookies().should('have.length', 1).then((cookies) => {
|
||||
expect(cookies[0].name).to.eq('key')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('src/cy/commands/cookies', () => {
|
||||
beforeEach(() => {
|
||||
// call through normally on everything
|
||||
|
||||
@@ -24,6 +24,27 @@ const clearAllSavedSessions = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// In webkit, the clear page and clear cookies, etc log messages may be reversed. This isn't an issue, but we just want to test we have both messages.
|
||||
const validateClearLogs = (logs, sessionGroupId) => {
|
||||
let clearPageLogIndex = 0
|
||||
let clearCookiesIndex = 1
|
||||
|
||||
if (logs[1].get('name') === 'Clear page') {
|
||||
clearPageLogIndex = 1
|
||||
clearCookiesIndex = 0
|
||||
}
|
||||
|
||||
expect(logs[clearPageLogIndex].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[clearCookiesIndex].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
}
|
||||
|
||||
describe('cy.session', { retries: 0 }, () => {
|
||||
describe('args', () => {
|
||||
it('accepts string as id', () => {
|
||||
@@ -200,15 +221,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const createNewSessionGroup = logs[3].get()
|
||||
|
||||
@@ -282,15 +295,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const createNewSessionGroup = logs[3].get()
|
||||
|
||||
@@ -344,15 +349,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const createNewSessionGroup = logs[3].get()
|
||||
|
||||
@@ -437,15 +434,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const restoreSavedSessionGroup = logs[3].get()
|
||||
|
||||
@@ -500,15 +489,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const restoreSavedSessionGroup = logs[3].get()
|
||||
|
||||
@@ -582,15 +563,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const restoreSavedSessionGroup = logs[3].get()
|
||||
|
||||
@@ -618,15 +591,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
|
||||
expect(logs[6].get('error').message).to.eq('Your `cy.session` **validate** callback returned false.')
|
||||
|
||||
expect(logs[7].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[8].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[7], logs[8]], sessionGroupId)
|
||||
|
||||
const createNewSessionGroup = logs[9].get()
|
||||
|
||||
@@ -692,15 +657,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
},
|
||||
})
|
||||
|
||||
expect(logs[1].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[2].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[1], logs[2]], sessionGroupId)
|
||||
|
||||
const restoreSavedSessionGroup = logs[3].get()
|
||||
|
||||
@@ -728,15 +685,7 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
|
||||
expect(logs[6].get('error').message).to.eq('Your `cy.session` **validate** callback returned false.')
|
||||
|
||||
expect(logs[7].get()).to.contain({
|
||||
name: 'Clear page',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
|
||||
expect(logs[8].get()).to.contain({
|
||||
displayName: 'Clear cookies, localStorage and sessionStorage',
|
||||
group: sessionGroupId,
|
||||
})
|
||||
validateClearLogs([logs[7], logs[8]], sessionGroupId)
|
||||
|
||||
const createNewSessionGroup = logs[9].get()
|
||||
|
||||
@@ -1046,7 +995,10 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
cy.once('fail', (err) => {
|
||||
expect(err.message).contain('Expected to find element: `#does_not_exist`')
|
||||
expect(err.message).contain(errorHookMessage)
|
||||
expect(err.codeFrame).exist
|
||||
// TODO: Webkit does not have correct stack traces on errors currently
|
||||
if (Cypress.isBrowser('!webkit')) {
|
||||
expect(err.codeFrame).exist
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -1064,7 +1016,11 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
cy.once('fail', (err) => {
|
||||
expect(err.message).contain('validate error')
|
||||
expect(err.message).contain(errorHookMessage)
|
||||
expect(err.codeFrame).exist
|
||||
// TODO: Webkit does not have correct stack traces on errors currently
|
||||
if (Cypress.isBrowser('!webkit')) {
|
||||
expect(err.codeFrame).exist
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
@@ -1081,7 +1037,10 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
cy.once('fail', (err) => {
|
||||
expect(err.message).contain('validate error')
|
||||
expect(err.message).contain(errorHookMessage)
|
||||
expect(err.codeFrame).exist
|
||||
// TODO: Webkit does not have correct stack traces on errors currently
|
||||
if (Cypress.isBrowser('!webkit')) {
|
||||
expect(err.codeFrame).exist
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -1099,7 +1058,10 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
cy.once('fail', (err) => {
|
||||
expect(err.message).to.contain('Your `cy.session` **validate** callback returned false.')
|
||||
expect(err.message).contain(errorHookMessage)
|
||||
expect(err.codeFrame).exist
|
||||
// TODO: Webkit does not have correct stack traces on errors currently
|
||||
if (Cypress.isBrowser('!webkit')) {
|
||||
expect(err.codeFrame).exist
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -1117,7 +1079,11 @@ describe('cy.session', { retries: 0 }, () => {
|
||||
cy.once('fail', (err) => {
|
||||
expect(err.message).to.contain('Your `cy.session` **validate** callback resolved false.')
|
||||
expect(err.message).contain(errorHookMessage)
|
||||
expect(err.codeFrame).exist
|
||||
// TODO: Webkit does not have correct stack traces on errors currently
|
||||
if (Cypress.isBrowser('!webkit')) {
|
||||
expect(err.codeFrame).exist
|
||||
}
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('basic login', () => {
|
||||
describe('basic login', { browser: '!webkit' }, () => {
|
||||
// Scenario, Token based auth. Visit site, redirect to IDP hosted on secondary origin, login and redirect back to site.
|
||||
describe('visit primary first', () => {
|
||||
it('logs in with idp redirect', () => {
|
||||
@@ -148,7 +148,7 @@ describe('basic login', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Multi-step Auth', () => {
|
||||
describe('Multi-step Auth', { browser: '!webkit' }, () => {
|
||||
// TODO: cy.origin does not work in cy.origin yet.
|
||||
it.skip('final auth redirects back to localhost - nested', () => {
|
||||
cy.visit('/fixtures/auth/index.html')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin actions', () => {
|
||||
context('cy.origin actions', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin aliasing', () => {
|
||||
context('cy.origin aliasing', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin assertions', () => {
|
||||
context('cy.origin assertions', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin connectors', () => {
|
||||
context('cy.origin connectors', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs, assertLogLength } from '../../../../support/utils'
|
||||
|
||||
describe('cy.origin cookies', () => {
|
||||
describe('cy.origin cookies', { browser: '!webkit' }, () => {
|
||||
context('client side', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin files', () => {
|
||||
context('cy.origin files', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin local storage', () => {
|
||||
context('cy.origin local storage', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin location', () => {
|
||||
context('cy.origin location', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { assertLogLength } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin log', () => {
|
||||
context('cy.origin log', { browser: '!webkit' }, () => {
|
||||
let logs: any = []
|
||||
let lastTestLogId = ''
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin misc', () => {
|
||||
context('cy.origin misc', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const { stripIndent } = require('common-tags')
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin navigation', () => {
|
||||
context('cy.origin navigation', { browser: '!webkit' }, () => {
|
||||
it('.go()', () => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin network requests', () => {
|
||||
context('cy.origin network requests', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="request-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin querying', () => {
|
||||
context('cy.origin querying', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin shadow dom', () => {
|
||||
context('cy.origin shadow dom', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="shadow-dom-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
context('cy.origin screenshot', () => {
|
||||
context('cy.origin screenshot', { browser: '!webkit' }, () => {
|
||||
const { devicePixelRatio } = window
|
||||
|
||||
context('set viewport', () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin spies, stubs, and clock', () => {
|
||||
context('cy.origin spies, stubs, and clock', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin traversal', () => {
|
||||
context('cy.origin traversal', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
context('cy.origin unsupported commands', () => {
|
||||
context('cy.origin unsupported commands', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin viewport', () => {
|
||||
context('cy.origin viewport', { browser: '!webkit' }, () => {
|
||||
it('syncs the viewport from the primary to secondary', () => {
|
||||
// change the viewport in the primary first
|
||||
cy.viewport(320, 480)
|
||||
|
||||
@@ -22,7 +22,7 @@ const abortRequests = () => {
|
||||
reqQueue = []
|
||||
}
|
||||
|
||||
context('cy.origin waiting', () => {
|
||||
context('cy.origin waiting', { browser: '!webkit' }, () => {
|
||||
before(() => {
|
||||
cy.origin('http://www.foobar.com:3500', () => {
|
||||
let reqQueue: XMLHttpRequest[] = []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { findCrossOriginLogs } from '../../../../support/utils'
|
||||
|
||||
context('cy.origin window', () => {
|
||||
context('cy.origin window', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="dom-link"]').click()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
['config', 'env'].forEach((fnName) => {
|
||||
describe(`cy.origin- Cypress.${fnName}()`, () => {
|
||||
describe(`cy.origin- Cypress.${fnName}()`, { browser: '!webkit' }, () => {
|
||||
const USED_KEYS = {
|
||||
foo: 'cy-origin-foo',
|
||||
bar: 'cy-origin-bar',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('Cookie Behavior with experimentalSessionAndOrigin=true', () => {
|
||||
describe('Cookie Behavior with experimentalSessionAndOrigin=true', { browser: '!webkit' }, () => {
|
||||
const makeRequest = (
|
||||
win: Cypress.AUTWindow,
|
||||
url: string,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
describe('cy.origin - cookie login', () => {
|
||||
describe('cy.origin - cookie login', { browser: '!webkit' }, () => {
|
||||
const { _ } = Cypress
|
||||
// ensures unique username so there's no risk of false positives from
|
||||
// test pollution
|
||||
@@ -71,7 +71,7 @@ describe('cy.origin - cookie login', () => {
|
||||
• displays "Welcome, <username>"
|
||||
****************************************************************************/
|
||||
|
||||
describe('general behavior', () => {
|
||||
describe('general behavior', { browser: '!webkit' }, () => {
|
||||
let username
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { assertLogLength } = require('../../../support/utils')
|
||||
|
||||
describe('cy.origin Cypress API', () => {
|
||||
describe('cy.origin Cypress API', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin dependencies - jsx', () => {
|
||||
describe('cy.origin dependencies - jsx', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin dependencies', () => {
|
||||
describe('cy.origin dependencies', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin', () => {
|
||||
describe('cy.origin', { browser: '!webkit' }, () => {
|
||||
it('window:before:load event', () => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.on('window:before:load', (win: {testPrimaryOriginBeforeLoad: boolean}) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { TemplateExecutor } from 'lodash'
|
||||
// NOTE: in order to run these tests, the following config flags need to be set
|
||||
// experimentalSessionAndOrigin=true
|
||||
// experimentalModifyObstructiveThirdPartyCode=true
|
||||
describe('Integrity Preservation', () => {
|
||||
describe('Integrity Preservation', { browser: '!webkit' }, () => {
|
||||
// Add common SRI hashes used when setting script/link integrity.
|
||||
// These are the ones supported by SRI (see https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity#using_subresource_integrity)
|
||||
// For our tests, we will use CryptoJS to calculate these hashes as they can regenerate the integrity without us having to do it manually every
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin logging', () => {
|
||||
describe('cy.origin logging', { browser: '!webkit' }, () => {
|
||||
const { _ } = Cypress
|
||||
|
||||
it('groups callback commands on a passing test', () => {
|
||||
|
||||
@@ -11,7 +11,7 @@ const reifyLogs = (logs) => {
|
||||
})
|
||||
}
|
||||
|
||||
describe('navigation events', () => {
|
||||
describe('navigation events', { browser: '!webkit' }, () => {
|
||||
let logs: any = []
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -185,7 +185,7 @@ describe('navigation events', () => {
|
||||
})
|
||||
|
||||
// @ts-ignore / session support is needed for visiting about:blank between tests
|
||||
describe('event timing', () => {
|
||||
describe('event timing', { browser: '!webkit' }, () => {
|
||||
it('does not timeout when receiving a delaying:html event after cy.origin has started, but before the spec bridge is ready', () => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
@@ -206,7 +206,7 @@ describe('event timing', () => {
|
||||
})
|
||||
|
||||
// @ts-ignore / session support is needed for visiting about:blank between tests
|
||||
describe('delayed navigation', { defaultCommandTimeout: 2000 }, () => {
|
||||
describe('delayed navigation', { browser: '!webkit' }, { defaultCommandTimeout: 2000 }, () => {
|
||||
it('localhost -> localhost', () => {
|
||||
cy.visit('/fixtures/auth/delayedNavigate.html')
|
||||
cy.get('[data-cy="to-localhost"]').click()
|
||||
@@ -245,7 +245,7 @@ describe('delayed navigation', { defaultCommandTimeout: 2000 }, () => {
|
||||
})
|
||||
|
||||
// @ts-ignore / session support is needed for visiting about:blank between tests
|
||||
describe('errors', () => {
|
||||
describe('errors', { browser: '!webkit' }, () => {
|
||||
it('never calls cy.origin', { defaultCommandTimeout: 50 }, (done) => {
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include(`Timed out retrying after 50ms:`)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin', () => {
|
||||
describe('cy.origin', { browser: '!webkit' }, () => {
|
||||
it('passes viewportWidth/Height state to the secondary origin', () => {
|
||||
const expectedViewport = [320, 480]
|
||||
|
||||
@@ -224,7 +224,9 @@ describe('cy.origin', () => {
|
||||
describe('errors', () => {
|
||||
it('propagates secondary origin errors to the primary that occur within the test', (done) => {
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('variable is not defined')
|
||||
const undefinedMessage = Cypress.isBrowser('webkit') ? 'Can\'t find variable: variable' : 'variable is not defined'
|
||||
|
||||
expect(err.message).to.include(undefinedMessage)
|
||||
expect(err.message).to.include(`Variables must either be defined within the \`cy.origin()\` command or passed in using the args option.`)
|
||||
expect(err.stack).to.include(`Variables must either be defined within the \`cy.origin()\` command or passed in using the args option.`)
|
||||
// make sure that the secondary origin failures do NOT show up as spec failures or AUT failures
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('src/cross-origin/patches', () => {
|
||||
describe('src/cross-origin/patches', { browser: '!webkit' }, () => {
|
||||
context('submit', () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-ignore
|
||||
describe('cy.origin - rerun', { }, () => {
|
||||
describe('cy.origin - rerun', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// import to bind shouldWithTimeout into global cy commands
|
||||
import '../../../support/utils'
|
||||
|
||||
describe('cy.origin - snapshots', () => {
|
||||
describe('cy.origin - snapshots', { browser: '!webkit' }, () => {
|
||||
const findLog = (logMap: Map<string, any>, displayName: string, url: string) => {
|
||||
return Array.from(logMap.values()).find((log: any) => {
|
||||
const props = log.get()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
it('visits foobar.com and types foobar inside an input', () => {
|
||||
it('visits foobar.com and types foobar inside an input', { browser: '!webkit' }, () => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('[data-cy="cross-origin-secondary-link"]').click()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin - uncaught errors', () => {
|
||||
describe('cy.origin - uncaught errors', { browser: '!webkit' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/fixtures/primary-origin.html')
|
||||
cy.get('a[data-cy="errors-link"]').click()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
describe('cy.origin', () => {
|
||||
describe('cy.origin', { browser: '!webkit' }, () => {
|
||||
describe('successes', () => {
|
||||
beforeEach(() => {
|
||||
// TODO: There seems to be a limit of 15 active spec bridges during a given test.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { assertLogLength } from '../../../support/utils'
|
||||
|
||||
describe('cy.origin yields', () => {
|
||||
describe('cy.origin yields', { browser: '!webkit' }, () => {
|
||||
let logs: any = []
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -9,17 +9,7 @@ describe('WebKit-specific behavior', { browser: 'webkit' }, () => {
|
||||
cy.origin('foo', () => {})
|
||||
})
|
||||
|
||||
it('cy.session() is disabled', (done) => {
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.equal('`cy.session()` is not currently supported in experimental WebKit.')
|
||||
expect(err.docsUrl).to.equal('https://on.cypress.io/webkit-experiment')
|
||||
done()
|
||||
})
|
||||
|
||||
cy.session('foo', () => {})
|
||||
})
|
||||
|
||||
it('cy.session() is disabled', (done) => {
|
||||
it('forceNetworkError intercept option is disabled', (done) => {
|
||||
cy.on('fail', (err) => {
|
||||
expect(err.message).to.include('`forceNetworkError` was passed, but it is not currently supported in experimental WebKit.')
|
||||
expect(err.docsUrl).to.equal('https://on.cypress.io/intercept')
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { client } from '@packages/socket/lib/browser'
|
||||
import { createWebsocket } from '@packages/socket/lib/browser'
|
||||
|
||||
export const handleSocketEvents = (Cypress) => {
|
||||
const webSocket = client({
|
||||
path: Cypress.config('socketIoRoute'),
|
||||
transports: ['websocket'],
|
||||
}).connect()
|
||||
const webSocket = createWebsocket({ path: Cypress.config('socketIoRoute'), browserFamily: Cypress.config('browser').family })
|
||||
|
||||
webSocket.connect()
|
||||
|
||||
const onBackendRequest = (...args) => {
|
||||
webSocket.emit('backend:request', ...args)
|
||||
|
||||
@@ -25,10 +25,6 @@ export default function (Commands, Cypress, cy) {
|
||||
// @ts-ignore
|
||||
|
||||
function throwIfNoSessionSupport () {
|
||||
if (Cypress.isBrowser('webkit')) {
|
||||
$errUtils.throwErrByPath('webkit.session')
|
||||
}
|
||||
|
||||
if (!Cypress.config('experimentalSessionAndOrigin')) {
|
||||
$errUtils.throwErrByPath('sessions.experimentNotEnabled', {
|
||||
args: {
|
||||
|
||||
@@ -551,22 +551,6 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
|
||||
|
||||
let isRunnerAbleToCommunicateWithAUT: boolean
|
||||
|
||||
if (this.Cypress.isBrowser('webkit')) {
|
||||
// WebKit's unhandledrejection event will sometimes not fire within the AUT
|
||||
// due to a documented bug: https://bugs.webkit.org/show_bug.cgi?id=187822
|
||||
// To ensure that the event will always fire (and always report these
|
||||
// unhandled rejections to the user), we patch the AUT's Error constructor
|
||||
// to enqueue a no-op microtask when executed, which ensures that the unhandledrejection
|
||||
// event handler will be executed if this Error is uncaught.
|
||||
const originalError = autWindow.Error
|
||||
|
||||
autWindow.Error = function __CyWebKitError (...args) {
|
||||
autWindow.queueMicrotask(() => {})
|
||||
|
||||
return originalError.apply(this, args)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Test to see if we can communicate with the AUT.
|
||||
autWindow.location.href
|
||||
@@ -581,6 +565,22 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert
|
||||
|
||||
// If the runner can communicate, we should setup all events, otherwise just setup the window and fire the load event.
|
||||
if (isRunnerAbleToCommunicateWithAUT) {
|
||||
if (this.Cypress.isBrowser('webkit')) {
|
||||
// WebKit's unhandledrejection event will sometimes not fire within the AUT
|
||||
// due to a documented bug: https://bugs.webkit.org/show_bug.cgi?id=187822
|
||||
// To ensure that the event will always fire (and always report these
|
||||
// unhandled rejections to the user), we patch the AUT's Error constructor
|
||||
// to enqueue a no-op microtask when executed, which ensures that the unhandledrejection
|
||||
// event handler will be executed if this Error is uncaught.
|
||||
const originalError = autWindow.Error
|
||||
|
||||
autWindow.Error = function __CyWebKitError (...args) {
|
||||
autWindow.queueMicrotask(() => {})
|
||||
|
||||
return originalError.apply(this, args)
|
||||
}
|
||||
}
|
||||
|
||||
setWindowDocumentProps(autWindow, this.state)
|
||||
|
||||
// we may need to update the url now
|
||||
|
||||
@@ -2352,7 +2352,6 @@ export default {
|
||||
webkit: {
|
||||
docsUrl: 'https://on.cypress.io/webkit-experiment',
|
||||
origin: '`cy.origin()` is not currently supported in experimental WebKit.',
|
||||
session: '`cy.session()` is not currently supported in experimental WebKit.',
|
||||
},
|
||||
|
||||
window: {
|
||||
|
||||
@@ -30,22 +30,26 @@ function convertSameSiteExtensionToCypress (str: CyCookie['sameSite']): 'None' |
|
||||
return str ? extensionMap[str] : undefined
|
||||
}
|
||||
|
||||
const normalizeGetCookieProps = (cookie: any): CyCookie => {
|
||||
if (cookie.expires === -1) {
|
||||
delete cookie.expires
|
||||
const normalizeGetCookieProps = ({ name, value, domain, path, secure, httpOnly, sameSite, expires }: playwright.Cookie): CyCookie => {
|
||||
const cyCookie: CyCookie = {
|
||||
name,
|
||||
value,
|
||||
domain,
|
||||
path,
|
||||
secure,
|
||||
httpOnly,
|
||||
hostOnly: false,
|
||||
// Use expirationDate instead of expires
|
||||
...expires !== -1 ? { expirationDate: expires } : {},
|
||||
}
|
||||
|
||||
// Use expirationDate instead of expires 🤷♀️
|
||||
cookie.expirationDate = cookie.expires
|
||||
delete cookie.expires
|
||||
|
||||
if (cookie.sameSite === 'None') {
|
||||
cookie.sameSite = 'no_restriction'
|
||||
} else if (cookie.sameSite) {
|
||||
cookie.sameSite = cookie.sameSite.toLowerCase()
|
||||
if (sameSite === 'None') {
|
||||
cyCookie.sameSite = 'no_restriction'
|
||||
} else if (sameSite) {
|
||||
cyCookie.sameSite = sameSite.toLowerCase() as CyCookie['sameSite']
|
||||
}
|
||||
|
||||
return cookie as CyCookie
|
||||
return cyCookie
|
||||
}
|
||||
|
||||
const normalizeSetCookieProps = (cookie: CyCookie): playwright.Cookie => {
|
||||
@@ -88,17 +92,33 @@ let requestIdCounter = 1
|
||||
const requestIdMap = new WeakMap<playwright.Request, string>()
|
||||
let downloadIdCounter = 1
|
||||
|
||||
type WebKitAutomationOpts = {
|
||||
automation: Automation
|
||||
browser: playwright.Browser
|
||||
shouldMarkAutIframeRequests: boolean
|
||||
initialUrl: string
|
||||
downloadsFolder: string
|
||||
videoApi?: RunModeVideoApi
|
||||
}
|
||||
|
||||
export class WebKitAutomation {
|
||||
automation: Automation
|
||||
private browser: playwright.Browser
|
||||
private context!: playwright.BrowserContext
|
||||
private page!: playwright.Page
|
||||
private shouldMarkAutIframeRequests: boolean
|
||||
|
||||
private constructor (public automation: Automation, private browser: playwright.Browser) {}
|
||||
private constructor (opts: WebKitAutomationOpts) {
|
||||
this.automation = opts.automation
|
||||
this.browser = opts.browser
|
||||
this.shouldMarkAutIframeRequests = opts.shouldMarkAutIframeRequests
|
||||
}
|
||||
|
||||
// static initializer to avoid "not definitively declared"
|
||||
static async create (automation: Automation, browser: playwright.Browser, initialUrl: string, downloadsFolder: string, videoApi?: RunModeVideoApi) {
|
||||
const wkAutomation = new WebKitAutomation(automation, browser)
|
||||
static async create (opts: WebKitAutomationOpts) {
|
||||
const wkAutomation = new WebKitAutomation(opts)
|
||||
|
||||
await wkAutomation.reset({ downloadsFolder, newUrl: initialUrl, videoApi })
|
||||
await wkAutomation.reset({ downloadsFolder: opts.downloadsFolder, newUrl: opts.initialUrl, videoApi: opts.videoApi })
|
||||
|
||||
return wkAutomation
|
||||
}
|
||||
@@ -127,6 +147,9 @@ export class WebKitAutomation {
|
||||
|
||||
let promises: Promise<any>[] = []
|
||||
|
||||
// TODO: remove with experimentalSessionAndOrigin
|
||||
if (this.shouldMarkAutIframeRequests) promises.push(this.markAutIframeRequests())
|
||||
|
||||
if (oldPwPage) promises.push(oldPwPage.context().close())
|
||||
|
||||
if (options.newUrl) promises.push(this.page.goto(options.newUrl))
|
||||
@@ -168,6 +191,28 @@ export class WebKitAutomation {
|
||||
})
|
||||
}
|
||||
|
||||
private async markAutIframeRequests () {
|
||||
function isAutIframeRequest (request: playwright.Request) {
|
||||
// is an iframe
|
||||
return (request.resourceType() === 'document')
|
||||
// is a top-level iframe (only 1 parent in chain)
|
||||
&& request.frame().parentFrame() && !request.frame().parentFrame()?.parentFrame()
|
||||
// is not the runner itself
|
||||
&& !request.url().includes('__cypress')
|
||||
}
|
||||
|
||||
await this.context.route('**', (route, request) => {
|
||||
if (!isAutIframeRequest(request)) return route.continue()
|
||||
|
||||
return route.continue({
|
||||
headers: {
|
||||
...request.headers(),
|
||||
'X-Cypress-Is-AUT-Frame': 'true',
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private handleDownloadEvents (downloadsFolder: string) {
|
||||
this.page.on('download', async (download) => {
|
||||
const id = downloadIdCounter++
|
||||
@@ -234,7 +279,7 @@ export class WebKitAutomation {
|
||||
})
|
||||
}
|
||||
|
||||
private async getCookies () {
|
||||
private async getCookies (): Promise<CyCookie[]> {
|
||||
const cookies = await this.context.cookies()
|
||||
|
||||
return cookies.map(normalizeGetCookieProps)
|
||||
@@ -256,8 +301,12 @@ export class WebKitAutomation {
|
||||
|
||||
return normalizeGetCookieProps(cookie)
|
||||
}
|
||||
|
||||
private async clearCookie (filter: CookieFilter) {
|
||||
/**
|
||||
* Clears one specific cookie
|
||||
* @param filter the cookie to be cleared
|
||||
* @returns the cleared cookie
|
||||
*/
|
||||
private async clearCookie (filter: CookieFilter): Promise<CookieFilter> {
|
||||
const allCookies = await this.context.cookies()
|
||||
const persistCookies = allCookies.filter((cookie) => {
|
||||
return !_cookieMatches(cookie, filter)
|
||||
@@ -265,6 +314,20 @@ export class WebKitAutomation {
|
||||
|
||||
await this.context.clearCookies()
|
||||
if (persistCookies.length) await this.context.addCookies(persistCookies)
|
||||
|
||||
return filter
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cookies
|
||||
* @returns cookies cleared
|
||||
*/
|
||||
private async clearCookies (): Promise<CyCookie[]> {
|
||||
const allCookies = await this.getCookies()
|
||||
|
||||
await this.context.clearCookies()
|
||||
|
||||
return allCookies
|
||||
}
|
||||
|
||||
private async takeScreenshot (data) {
|
||||
@@ -293,7 +356,7 @@ export class WebKitAutomation {
|
||||
case 'set:cookies':
|
||||
return await this.context.addCookies(data.map(normalizeSetCookieProps))
|
||||
case 'clear:cookies':
|
||||
return await this.context.clearCookies()
|
||||
return await this.clearCookies()
|
||||
case 'clear:cookie':
|
||||
return await this.clearCookie(data)
|
||||
case 'take:screenshot':
|
||||
|
||||
@@ -92,7 +92,15 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc
|
||||
|
||||
const pwBrowser = await pw.webkit.connect(pwServer.wsEndpoint())
|
||||
|
||||
wkAutomation = await WebKitAutomation.create(automation, pwBrowser, url, options.downloadsFolder, options.videoApi)
|
||||
wkAutomation = await WebKitAutomation.create({
|
||||
automation,
|
||||
browser: pwBrowser,
|
||||
initialUrl: url,
|
||||
downloadsFolder: options.downloadsFolder,
|
||||
shouldMarkAutIframeRequests: !!options.experimentalSessionAndOrigin,
|
||||
videoApi: options.videoApi,
|
||||
})
|
||||
|
||||
automation.use(wkAutomation)
|
||||
|
||||
class WkInstance extends EventEmitter implements BrowserInstance {
|
||||
|
||||
@@ -5,3 +5,12 @@ export type { Socket } from 'socket.io-client'
|
||||
export {
|
||||
io as client,
|
||||
}
|
||||
|
||||
export function createWebsocket ({ path, browserFamily }: { path: string, browserFamily: string}) {
|
||||
return io({
|
||||
path,
|
||||
// TODO(webkit): the websocket socket.io transport is busted in WebKit, need polling
|
||||
// https://github.com/cypress-io/cypress/issues/23807
|
||||
transports: browserFamily === 'webkit' ? ['polling'] : ['websocket'],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,6 +21,24 @@ describe('Socket', function () {
|
||||
expect(browserLib.client).to.eq(client)
|
||||
})
|
||||
|
||||
it('exports createWebSocket from lib/browser', function () {
|
||||
expect(browserLib.createWebsocket).to.be.defined
|
||||
})
|
||||
|
||||
it('creates a websocket for non webkit browsers', function () {
|
||||
const socket = browserLib.createWebsocket({ path: '/path', browserFamily: 'chromium' })
|
||||
|
||||
expect(socket.io.opts.path).to.eq('/path')
|
||||
expect(socket.io.opts.transports[0]).to.eq('websocket')
|
||||
})
|
||||
|
||||
it('creates a websocket for non webkit browsers', function () {
|
||||
const socket = browserLib.createWebsocket({ path: '/path', browserFamily: 'webkit' })
|
||||
|
||||
expect(socket.io.opts.path).to.eq('/path')
|
||||
expect(socket.io.opts.transports[0]).to.eq('polling')
|
||||
})
|
||||
|
||||
context('.getPathToClientSource', function () {
|
||||
it('returns path to socket.io.js', function () {
|
||||
const clientPath = path.join(resolvePkg('socket.io-client'), 'dist', 'socket.io.js')
|
||||
|
||||
Reference in New Issue
Block a user