Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into issue-7306-refacto…
Browse files Browse the repository at this point in the history
…rAssertionLogging
  • Loading branch information
BlueWinds committed Aug 17, 2022
2 parents 971c272 + 53f0a02 commit 0a50757
Show file tree
Hide file tree
Showing 38 changed files with 1,087 additions and 56 deletions.
4 changes: 2 additions & 2 deletions browser-versions.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"chrome:beta": "105.0.5195.19",
"chrome:stable": "104.0.5112.79"
"chrome:beta": "105.0.5195.28",
"chrome:stable": "104.0.5112.101"
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cypress",
"version": "10.5.0",
"version": "10.6.0",
"description": "Cypress.io end to end testing tool",
"private": true,
"scripts": {
Expand Down
2 changes: 2 additions & 0 deletions packages/app/cypress/component/support/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/// <reference path="../../../../frontend-shared/cypress/support/component.ts" />
import '../../../../frontend-shared/cypress/support/component.ts'
import { registerMountFn } from '@packages/frontend-shared/cypress/support/common'
// ***********************************************************
// This example support/index.ts is processed and
Expand Down
9 changes: 1 addition & 8 deletions packages/app/cypress/e2e/specs_list_flaky.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,7 @@ describe('App: Spec List - Flaky Indicator', () => {

cy.remoteGraphQLIntercept(async (obj) => {
await new Promise((r) => setTimeout(r, 20))
if (obj.result.data && 'cloudProjectBySlug' in obj.result.data) {
obj.result.data.cloudProjectBySlug = {
__typename: 'CloudProject',
retrievedAt: new Date().toISOString(),
id: `id${obj.variables.slug}`,
projectId: 'abc123',
}
} else if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
if (obj.result.data && 'cloudSpecByPath' in obj.result.data) {
if (obj.variables.specPath.includes('123.spec.js')) {
obj.result.data.cloudSpecByPath = {
__typename: 'CloudProjectSpec',
Expand Down
2 changes: 1 addition & 1 deletion packages/app/cypress/e2e/specs_list_latest_runs.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ describe('App/Cloud Integration - Latest runs and Average duration', { viewportW
cy.get(averageDurationSelector('accounts_new.spec.js')).contains('2:03')
})

it('lazily loads data for off-screen specs', () => {
it('lazily loads data for off-screen specs', { viewportHeight: 500 }, () => {
// make sure the virtualized list didn't load z008.spec.js
cy.get(specRowSelector('z008.spec.js')).should('not.exist')

Expand Down
2 changes: 2 additions & 0 deletions packages/app/cypress/e2e/top-nav.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ describe('Growth Prompts Can Open Automatically', () => {
firstOpened: 1609459200000,
lastOpened: 1609459200000,
promptsShown: {},
banners: { _disabled: true },
})
},
)
Expand All @@ -672,6 +673,7 @@ describe('Growth Prompts Can Open Automatically', () => {
firstOpened: 1609459200000,
lastOpened: 1609459200000,
promptsShown: { ci1: 1609459200000 },
banners: { _disabled: true },
})
},
)
Expand Down
21 changes: 21 additions & 0 deletions packages/app/src/runner/event-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,27 @@ export class EventManager {
Cypress.primaryOriginCommunicator.toAllSpecBridges('before:unload')
})

Cypress.on('request:snapshot:from:spec:bridge', ({ log, name, options, specBridge, addSnapshot }: {
log: Cypress.Log
name?: string
options?: any
specBridge: string
addSnapshot: (snapshot: any, options: any, shouldRebindSnapshotFn: boolean) => Cypress.Log
}) => {
const eventID = log.get('id')

Cypress.primaryOriginCommunicator.once(`snapshot:for:log:generated:${eventID}`, (generatedCrossOriginSnapshot) => {
const snapshot = generatedCrossOriginSnapshot.body ? generatedCrossOriginSnapshot : null

addSnapshot.apply(log, [snapshot, options, false])
})

Cypress.primaryOriginCommunicator.toSpecBridge(specBridge, 'generate:snapshot:for:log', {
name,
id: eventID,
})
})

Cypress.primaryOriginCommunicator.on('window:load', ({ url }, originPolicy) => {
// Sync stable if the expected origin has loaded.
// Only listen to window load events from the most recent secondary origin, This prevents nondeterminism in the case where we redirect to an already
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/runner/iframe-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export class IframeModel {
* The spec bridge that matches the origin policy will take a snapshot and send it back to the primary for the runner to store in originalState.
*/
Cypress.primaryOriginCommunicator.toAllSpecBridges('generate:final:snapshot', autStore.url || '')
Cypress.primaryOriginCommunicator.once('final:snapshot:generated', (finalSnapshot) => {
Cypress.primaryOriginCommunicator.once('snapshot:final:generated', (finalSnapshot) => {
// todo(lachlan): UNIFY-1318 - find correct default, if they are even needed, for required fields ($el, coords...)
// @ts-ignore
this.originalState = {
Expand Down
167 changes: 166 additions & 1 deletion packages/app/src/specs/SpecsListBanners.cy.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import SpecsListBanners from './SpecsListBanners.vue'
import { ref } from 'vue'
import type { Ref } from 'vue'
import { SpecsListBannersFragmentDoc } from '../generated/graphql-test'
import { SpecsListBannersFragment, SpecsListBannersFragmentDoc } from '../generated/graphql-test'
import interval from 'human-interval'
import { CloudUserStubs, CloudProjectStubs } from '@packages/graphql/test/stubCloudTypes'
import { AllowedState, BannerIds } from '@packages/types'
import { assignIn, set } from 'lodash'

const AlertSelector = 'alert-header'
const AlertCloseBtnSelector = 'alert-suffix-icon'

type BannerKey = keyof typeof BannerIds
type BannerId = typeof BannerIds[BannerKey]

describe('<SpecsListBanners />', () => {
const validateBaseRender = () => {
it('should render as expected', () => {
Expand Down Expand Up @@ -48,6 +55,75 @@ describe('<SpecsListBanners />', () => {
})
}

const stateWithFirstOpenedDaysAgo = (days: number) => {
return {
firstOpened: Date.now() - interval(`${days} days`),
}
}

const mountWithState = (query: Partial<SpecsListBannersFragment>, state?: Partial<AllowedState>, props?: object) => {
cy.mountFragment(SpecsListBannersFragmentDoc, {
onResult: (result) => {
assignIn(result, query)
set(result, 'currentProject.savedState', state)
},
render: (gql) => <SpecsListBanners gql={gql} {...props} />,
})
}

const validateSmartNotificationBehaviors = (bannerId: BannerId, bannerTestId: string, gql: Partial<SpecsListBannersFragment>) => {
it('should not render when using cypress < 4 days', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(3))

cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

it('should not render when previously-dismissed', () => {
mountWithState(gql, {
...stateWithFirstOpenedDaysAgo(4),
banners: {
[bannerId]: {
dismissed: Date.now(),
},
},
})

cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

context('banner conditions are met and when cypress use >= 4 days', () => {
it('should render when not previously-dismissed', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4))
cy.get(`[data-cy="${bannerTestId}"]`).should('be.visible')
})

it('should be preempted by spec not found banner', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isSpecNotFound: true })
cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

it('should be preempted by offline warning banner', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isOffline: true })
cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

it('should be preempted by fetch error banner', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isFetchError: true })
cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

it('should be preempted by project not found banner', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isProjectNotFound: true })
cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})

it('should be preempted by request access banner', () => {
mountWithState(gql, stateWithFirstOpenedDaysAgo(4), { isProjectUnauthorized: true })
cy.get(`[data-cy="${bannerTestId}"]`).should('not.exist')
})
})
}

describe('spec not found', () => {
const visible: any = ref(true)

Expand Down Expand Up @@ -141,6 +217,7 @@ describe('<SpecsListBanners />', () => {
message: 'test',
hasRequestedAccess: false,
},
savedState: {},
}
},
render: (gql) => <SpecsListBanners gql={gql} isProjectUnauthorized={visible} />,
Expand Down Expand Up @@ -170,6 +247,7 @@ describe('<SpecsListBanners />', () => {
message: 'test',
hasRequestedAccess: true,
},
savedState: {},
}
},
render: (gql) => <SpecsListBanners gql={gql} isProjectUnauthorized={visible} hasRequestedAccess />,
Expand All @@ -181,4 +259,91 @@ describe('<SpecsListBanners />', () => {
validateCloseOnPropChange(visible)
validateReopenOnPropChange(visible)
})

describe('login', () => {
const gql: Partial<SpecsListBannersFragment> = {
cloudViewer: null,
cachedUser: null,
currentProject: {
__typename: 'CurrentProject',
id: 'abc123',
} as any,
}

validateSmartNotificationBehaviors(BannerIds.ACI_082022_LOGIN, 'login-banner', gql)
})

describe('create organization', () => {
const gql: Partial<SpecsListBannersFragment> = {
cloudViewer: {
...CloudUserStubs.me,
firstOrganization: {
__typename: 'CloudOrganizationConnection',
nodes: [],
},
},
currentProject: {
__typename: 'CurrentProject',
id: 'abc123',
} as any,
}

beforeEach(() => {
cy.gqlStub.Query.cloudViewer = gql.cloudViewer as any
})

validateSmartNotificationBehaviors(BannerIds.ACI_082022_CREATE_ORG, 'create-organization-banner', gql)
})

describe('connect project', () => {
const gql: Partial<SpecsListBannersFragment> = {
cloudViewer: {
...CloudUserStubs.me,
firstOrganization: {
__typename: 'CloudOrganizationConnection',
nodes: [{ __typename: 'CloudOrganization', id: '987' }],
},
},
currentProject: {
__typename: 'CurrentProject',
id: 'abc123',
projectId: null,
} as any,
}

validateSmartNotificationBehaviors(BannerIds.ACI_082022_CONNECT_PROJECT, 'connect-project-banner', gql)
})

describe('record', () => {
const gql: Partial<SpecsListBannersFragment> = {
cloudViewer: {
...CloudUserStubs.me,
firstOrganization: {
__typename: 'CloudOrganizationConnection',
nodes: [{ __typename: 'CloudOrganization', id: '987' }],
},
},
currentProject: {
__typename: 'CurrentProject',
id: 'abc123',
title: 'my-test-project',
currentTestingType: 'component',
projectId: 'abcd',
cloudProject: {
...CloudProjectStubs.componentProject,
runs: {
__typename: 'CloudRunConnection',
nodes: [],
},
},
} as any,
}

beforeEach(() => {
cy.gqlStub.Query.currentProject = gql.currentProject as any
cy.gqlStub.Query.cloudViewer = gql.cloudViewer as any
})

validateSmartNotificationBehaviors(BannerIds.ACI_082022_RECORD, 'record-banner', gql)
})
})
Loading

0 comments on commit 0a50757

Please sign in to comment.