Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add v13 welcome page content #27549

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/data-context/src/data/coreDataShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export interface WizardDataShape {
export interface MigrationDataShape {
// TODO: have the model of migration here
step: MigrationStep
videoEmbedHtml: string | null
legacyConfigForMigration?: LegacyCypressConfigJson | null
filteredSteps: MigrationStep[]
flags: {
Expand Down Expand Up @@ -214,6 +215,7 @@ export function makeCoreData (modeOptions: Partial<AllModeOptions> = {}): CoreDa
},
migration: {
step: 'renameAuto',
videoEmbedHtml: null,
legacyConfigForMigration: null,
filteredSteps: [...MIGRATION_STEPS],
flags: {
Expand Down
31 changes: 31 additions & 0 deletions packages/data-context/src/sources/MigrationDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,37 @@ export class MigrationDataSource {
return this.ctx.lifecycleManager.metaState.needsCypressJsonMigration && Boolean(legacyConfigFileExists)
}

async getVideoEmbedHtml () {
if (this.ctx.coreData.migration.videoEmbedHtml) {
return this.ctx.coreData.migration.videoEmbedHtml
}

const versionData = await this.ctx.versions.versionData()
const embedOnLink = `https://on.cypress.io/v13-video-embed/${versionData.current.version}`

debug(`Getting videoEmbedHtml at link: ${embedOnLink}`)

// Time out request if it takes longer than 3 seconds
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 3000)

try {
const response = await this.ctx.util.fetch(embedOnLink, { method: 'GET', signal: controller.signal })
const { videoHtml } = await response.json()

this.ctx.update((d) => {
d.migration.videoEmbedHtml = videoHtml
})

return videoHtml
} catch {
// fail silently, no user-facing error is needed
return null
} finally {
clearTimeout(timeoutId)
}
}

async getComponentTestingMigrationStatus () {
debug('getComponentTestingMigrationStatus: start')
if (!this.legacyConfig || !this.ctx.currentProject) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,13 @@ export const stubQuery: MaybeResolver<Query> = {
scaffoldedFiles () {
return null
},
videoEmbedHtml () {
return `<iframe
src="https://player.vimeo.com/video/855168407?h=0cbc785eef"
class="rounded h-full bg-gray-1000 w-full"
frameborder="0"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
/>`
},
}
3 changes: 3 additions & 0 deletions packages/graphql/schemas/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,9 @@ type Query {
"""Previous versions of cypress and their release date"""
versions: VersionData

"""Markup for the migration landing page video embed"""
videoEmbedHtml: String

"""A list of warnings"""
warnings: [ErrorWrapper!]!

Expand Down
11 changes: 11 additions & 0 deletions packages/graphql/src/schemaTypes/objectTypes/gql-Query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ export const Query = objectType({
description: 'Unique node machine identifier for this instance - may be nil if unable to resolve',
resolve: async (source, args, ctx) => await ctx.coreData.machineId,
})

t.string('videoEmbedHtml', {
description: 'Markup for the migration landing page video embed',
resolve: (source, args, ctx) => {
// NOTE: embedded video is not always a part of the v9 - v10 migration experience
// in the case of v1x - v13, we want to show an embedded video to users installing the major
// version for the first time without going through the steps of the migration resolver, hence
// why this lives in the root resolver but the migration context
return ctx.migration.getVideoEmbedHtml()
},
})
},
sourceType: {
module: '@packages/graphql',
Expand Down
66 changes: 66 additions & 0 deletions packages/launchpad/cypress/e2e/migration.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ProjectFixtureDir } from '@tooling/system-tests'
import type { SinonStub } from 'sinon'
import { getPathForPlatform } from './support/getPathForPlatform'

// @ts-ignore
Expand Down Expand Up @@ -1731,3 +1732,68 @@ describe('Migrate custom config files', () => {
cy.contains(err)
})
})

describe('v13 migration welcome page with video', () => {
function stubVideoHtml (): void {
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.migration, 'getVideoEmbedHtml').callsFake(async () => {
return '<span>Stubbed Video Content</span>'
})
})
}

function unstubVideoHtml (): void {
cy.withCtx((ctx, o) => {
const restoreFn = (ctx.migration.getVideoEmbedHtml as SinonStub).restore

restoreFn?.()
})
}

beforeEach(() => {
stubVideoHtml()
})

it('Welcome page should appear if video is not present', () => {
unstubVideoHtml()

cy.scaffoldProject('migration-v12-to-v13')
cy.openProject('migration-v12-to-v13')
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.migration, 'getVideoEmbedHtml').callsFake(async () => {
return null
})
})

cy.visitLaunchpad()
cy.contains(cy.i18n.majorVersionWelcome.title).should('be.visible')
cy.get('[data-cy="video-container"]').should('not.exist')
})

it('Welcome page should appear if video is present', () => {
unstubVideoHtml()

cy.scaffoldProject('migration-v12-to-v13')
cy.openProject('migration-v12-to-v13')

cy.visitLaunchpad()
cy.contains(cy.i18n.majorVersionWelcome.title).should('be.visible')
cy.get('[data-cy="video-container"]').should('be.visible')
})

it('should only hit the video on link once & cache it', () => {
unstubVideoHtml()

cy.scaffoldProject('migration-v12-to-v13')
cy.openProject('migration-v12-to-v13')

cy.visitLaunchpad()
cy.contains(cy.i18n.majorVersionWelcome.title).should('be.visible')

cy.visitLaunchpad()
cy.contains(cy.i18n.majorVersionWelcome.title).should('be.visible')
cy.withCtx((ctx, o) => {
expect((ctx.util.fetch as SinonStub).args.filter((a) => String(a[0]).includes('v13-video-embed')).length).to.eq(1)
})
})
})
21 changes: 20 additions & 1 deletion packages/launchpad/src/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@
<MajorVersionWelcome
v-if="shouldShowWelcome"
class="pt-[64px]"
:video-html="videoHtml"
@clearLandingPage="handleClearLandingPage"
/>
>
<template
v-if="videoHtml"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this pass if videoHtml is ''?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not. v-if only evaluates with the expression is truthy https://vuejs.org/guide/essentials/conditional.html#v-if

#video
>
<div
class="major-version-welcome-video"
v-html="videoHtml"
/>
</template>
</MajorVersionWelcome>
<div
v-else
class="px-[24px] pt-[86px] pb-[24px]"
Expand Down Expand Up @@ -134,6 +145,7 @@ fragment MainLaunchpadQueryData on Query {
id
}
}
videoEmbedHtml
isGlobalMode
...GlobalPage
...ScaffoldedFiles
Expand Down Expand Up @@ -213,4 +225,11 @@ const shouldShowWelcome = computed(() => {
return false
})

const videoHtml = computed(() => query.data.value?.videoEmbedHtml || '')

</script>
<style scoped lang="scss">
.major-version-welcome-video {
aspect-ratio: 15/9;
}
</style>
26 changes: 12 additions & 14 deletions packages/launchpad/src/migration/MajorVersionWelcome.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@ describe('<MajorVersionWelcome />', { viewportWidth: 1280, viewportHeight: 1400
it('renders expected interactive content', () => {
const continueStub = cy.stub().as('clearLandingPage')

cy.mount(<MajorVersionWelcome onClearLandingPage={continueStub} />)
cy.mount(<MajorVersionWelcome onClearLandingPage={continueStub}/>)

cy.contains('h1', 'What\'s New in Cypress').should('be.visible')

cy.get('[data-cy="release-highlights"]').within(() => {
cy.contains('a[href="https://on.cypress.io/changelog#12-0-0"]', '12.0.0')
cy.contains('a[href="https://on.cypress.io/changelog#12-0-0"]', 'changelog')
cy.contains('a[href="https://on.cypress.io/migration-guide#Migrating-to-Cypress-12-0"]', 'Migration Guide')

cy.contains('a[href="https://on.cypress.io/origin"]', 'cy.origin()')
cy.contains('a[href="https://on.cypress.io/session"]', 'cy.session()')
cy.contains('a[href="https://on.cypress.io/retry-ability"]', 'Retry-ability Guide')
cy.contains('a[href="https://on.cypress.io/changelog?utm_source=splash-page&utm_campaign=v13#13-0-0"]', '13.0.0')
cy.contains('a[href="https://on.cypress.io/changelog?utm_source=splash-page&utm_campaign=v13#13-0-0"]', 'changelog')
})

cy.get('[data-cy="previous-release-highlights"]').within(() => {
cy.contains('a[href="https://on.cypress.io/changelog#12-0-0"]', '12.0.0')
cy.contains('a[href="https://on.cypress.io/changelog#11-0-0"]', '11.0.0')
cy.contains('a[href="https://on.cypress.io/changelog#10-0-0"]', '10.0.0')
})
Expand All @@ -37,15 +33,17 @@ describe('<MajorVersionWelcome />', { viewportWidth: 1280, viewportHeight: 1400
})

it('renders correct time for releases and overflows correctly', () => {
cy.clock(Date.UTC(2022, 10, 8))
cy.clock(Date.UTC(2023, 7, 30))
cy.mount(<MajorVersionWelcome />)
cy.contains('11.0.0 Released just now')
cy.contains('10.0.0 Released 5 months ago')
cy.contains('13.0.0 Released just now')
cy.contains('12.0.0 Released 9 months ago')
cy.contains('11.0.0 Released 10 months ago')
cy.contains('10.0.0 Released last year')
cy.tick(interval('1 minute'))
cy.contains('11.0.0 Released 1 minute ago')
cy.contains('13.0.0 Released 1 minute ago')
cy.tick(interval('1 month'))
cy.contains('11.0.0 Released last month')
cy.contains('10.0.0 Released 6 months ago')
cy.contains('13.0.0 Released last month')
cy.contains('12.0.0 Released 10 months ago')

cy.viewport(1280, 500)

Expand Down
Loading