Merge branch '10.0-release' into 10.0-release-merge-develop-03-22

This commit is contained in:
Barthélémy Ledoux
2022-03-23 18:04:20 -04:00
committed by GitHub
18 changed files with 100 additions and 44 deletions
-3
View File
@@ -29,7 +29,6 @@ mainBuildFilters: &mainBuildFilters
only:
- develop
- 10.0-release
- UNIFY-1294-specs-list-flake
# usually we don't build Mac app - it takes a long time
# but sometimes we want to really confirm we are doing the right thing
@@ -39,7 +38,6 @@ macWorkflowFilters: &mac-workflow-filters
or:
- equal: [ develop, << pipeline.git.branch >> ]
- equal: [ '10.0-release', << pipeline.git.branch >> ]
- equal: [ UNIFY-1294-specs-list-flake, << pipeline.git.branch >> ]
- matches:
pattern: "-release$"
value: << pipeline.git.branch >>
@@ -49,7 +47,6 @@ windowsWorkflowFilters: &windows-workflow-filters
or:
- equal: [ develop, << pipeline.git.branch >> ]
- equal: [ '10.0-release', << pipeline.git.branch >> ]
- equal: [ UNIFY-1294-specs-list-flake, << pipeline.git.branch >> ]
- matches:
pattern: "-release$"
value: << pipeline.git.branch >>
+1 -1
View File
@@ -126,7 +126,7 @@ describe('App: Index', () => {
expectedScaffoldPaths.forEach((spec) => {
// Validate that links for each generated spec are rendered
cy.get(`a[href="#/specs/runner?file=${spec}"`).scrollIntoView().should('exist')
cy.get(`a[href="${getRunnerHref(spec)}"`).scrollIntoView().should('exist')
})
})
@@ -51,9 +51,10 @@ export function testUrqlClient (context: ClientTestContext,
if (firstMutation.kind === 'OperationDefinition') {
const mutationName = firstMutation.name?.value
const mutationResolver = mutationName && mutationResolvers.get(mutationName)
if (mutationName && mutationResolvers[mutationName]) {
const val = mutationResolvers[mutationName]((conf: any) => (conf), result.operation.variables)
if (mutationResolver) {
const val = mutationResolver((conf: any) => (conf), result.operation.variables)
if (val) {
result.data = val
@@ -150,7 +150,7 @@ export const registerMountFn = ({ plugins }: MountFnOptions = {}) => {
const definition = document.definitions[0]
if (definition.kind === 'OperationDefinition' && definition.name) {
mutationResolvers[definition.name.value] = resolver
mutationResolvers.set(definition.name.value, resolver)
} else {
throw new Error('only use mutation documents in stubMutationResolver first argument')
}
@@ -101,7 +101,7 @@ describe('<Select />', () => {
})
describe('#icons', () => {
// TODO: Fix this
// TODO: Enable with completion of UNIFY-1375
it.skip('marks the selected item with a check by default', () => {
mountSelect().then(openSelect)
.then(selectFirstOption)
@@ -1,4 +1,5 @@
import CopyButton from './CopyButton.vue'
import { Clipboard_CopyToClipboardDocument } from '../generated/graphql'
describe('<CopyButton />', { viewportHeight: 80, viewportWidth: 120 }, () => {
it('copies text to clipboard', () => {
@@ -7,13 +8,23 @@ describe('<CopyButton />', { viewportHeight: 80, viewportWidth: 120 }, () => {
</>))
.get('button')
.should('contain.text', 'Copy')
.get('svg')
.should('exist')
// TODO: UNIFY-999 Solve "write permission denied" error to test this in run mode
// cy.findByRole('button', { name: 'Copy' }).realClick()
// cy.findByRole('button', { name: 'Copied!' }).should('be.visible')
const copyStub = cy.stub()
cy.stubMutationResolver(Clipboard_CopyToClipboardDocument, (defineResult, { text }) => {
copyStub(text)
return defineResult({
copyTextToClipboard: true,
})
})
cy.findByRole('button', { name: 'Copy' }).click()
cy.findByRole('button', { name: 'Copied!' }).should('be.visible')
cy.wrap(copyStub).should('have.been.calledWith', 'Foobar')
})
it('noIcon hides the icon', () => {
@@ -1,12 +1,12 @@
declare global {
namespace Cypress {
interface Chainable {
attachFileWithPath: (path: string) => Chainable<HTMLInputElement>
attachFileWithPath: (path: string) => Chainable<JQuery<HTMLInputElement>>
}
}
}
export function attachedFileWithPath (subject: HTMLInputElement, path: string) {
export function attachFileWithPath (subject, path: string) {
const attachedFile = new File([new Blob()], 'cypress.config.ts')
Object.defineProperty(attachedFile, 'path', { value: path })
@@ -22,6 +22,5 @@ export function attachedFileWithPath (subject: HTMLInputElement, path: string) {
Cypress.Commands.add(
'attachFileWithPath',
{ prevSubject: true },
// TODO: Figure out why https://github.com/cypress-io/cypress/pull/19003 isn't fixing this?
attachedFileWithPath as any,
attachFileWithPath,
)
@@ -906,7 +906,8 @@ describe('Full migration flow for each project', { retries: { openMode: 2, runMo
})
})
// TODO: toLaunchpad emitter not working in Cypress in Cypress.
// TODO: UNIFY-1350 toLaunchpad emitter not working in Cypress in Cypress,
// re-evaluate after conversion to subscriptions
describe.skip('component testing migration - defaults', () => {
it('live update migration UI as user moves files', () => {
cy.scaffoldProject('migration-component-testing-customized')
@@ -122,11 +122,7 @@ describe('Launchpad: Setup Project', () => {
cy.get('@aboutTestingTypes').should('not.exist')
})
// Cypress enter key down isn't trigger close callback. Working correctly when manually tested
// or when using the cypress-real-evens plugin.
// Could be related to this bug? https://github.com/cypress-io/cypress/issues/14864
// FIXME: https://github.com/cypress-io/cypress/pull/19726
it.skip('closes modal by pressing enter key when close button is focused', () => {
it('closes modal by pressing enter key when close button is focused', () => {
cy.contains('Review the differences').click()
cy.get('#app').should('have.attr', 'aria-hidden', 'true')
@@ -136,10 +132,8 @@ describe('Launchpad: Setup Project', () => {
.within(() => {
cy.get('h2').contains('Key Differences').should('be.visible')
cy.tabUntil((el) => el.text().includes('Close'))
cy.findByRole('button', { name: 'Close' })
.should('have.focus')
.focus()
.type('{enter}')
})
@@ -29,27 +29,40 @@ describe('FileRow', () => {
content={content}
filePath="cypress/integration/support.ts"
description={description}
fileExtension=".ts"
/>
<FileRow
status="changes"
content={content}
filePath="cypress/integration/command.js"
description={description}
fileExtension=".js"
/>
<FileRow
status="skipped"
content={content}
filePath="cypress.config.js"
description={description}
fileExtension=".js"
/>
<FileRow
status="error"
content={content}
filePath="cypress/integration/index.js"
description={description}
fileExtension=".js"
/>
</div>
))
cy.get('pre.shiki').should('exist')
cy.contains('cypress/integration/support.ts')
cy.contains('cypress/integration/command.js')
cy.contains('cypress.config.js')
cy.contains('cypress/integration/index.js')
cy.percySnapshot()
})
it('opens on click', () => {
@@ -60,12 +73,14 @@ describe('FileRow', () => {
content={content}
filePath="cypress/integration/support.js"
description={description}
fileExtension=".js"
/>
<FileRow
status="changes"
content={content}
filePath="cypress/integration/command.js"
description={description}
fileExtension=".js"
/>
</div>
))
@@ -75,7 +90,11 @@ describe('FileRow', () => {
cy.contains(messages.changesRequiredBadge).should('not.exist') // Hide badge when row is expanded
cy.contains(changesRequiredDescription).should('be.visible')
cy.get('pre').should('have.length', 2)
cy.percySnapshot('row starts open')
cy.contains('cypress/integration/command.js').click()
cy.percySnapshot('row collapses after click')
})
it('responds nice to small screens', { viewportWidth: 500 }, () => {
@@ -88,6 +107,7 @@ describe('FileRow', () => {
content={content}
filePath="cypress/integration/command.js"
description={lorem}
fileExtension=".js"
/>
</div>
))
@@ -97,5 +117,7 @@ describe('FileRow', () => {
cy.contains(messages.changesRequiredBadge).should('not.exist')
cy.contains(changesRequiredDescription).should('be.visible')
cy.get('pre').should('exist')
cy.percySnapshot()
})
})
@@ -96,12 +96,13 @@ const props = defineProps<{
filePath: string
content: string
description?: string
fileExtension: string
}>()
// TODO: Remove this. Use FileParts when available
const language = computed(() => {
// get the extension of the current file path
const extension = /\.(\w+)$/.exec(props.filePath)?.[1]
// The fileExtension from FileParts is prepended with a period;
// we must strip the period to validate against our supported languages.
let extension = props.fileExtension.replace(/^\./, '')
if (extension && (langsSupported as readonly string[]).includes(extension)) {
return extension as CyLangType
@@ -100,7 +100,8 @@ withDefaults(defineProps<{
})
onMounted(() => {
// TODO: remove this when vue3-file-selector supports setting this attribute
// vue3-file-selector does not support setting these attributes through props,
// so we add them directly after mounting.
const fileRef = projectUpload.value?.querySelector('input[type=file]')
fileRef?.setAttribute('webkitdirectory', 'webkitdirectory')
@@ -1,7 +1,7 @@
import { defaultMessages } from '@cy/i18n'
import GlobalPage from './GlobalPage.vue'
import type { GlobalPageFragment } from '../generated/graphql-test'
import { GlobalPageFragmentDoc } from '../generated/graphql-test'
import { GlobalPageFragmentDoc, GlobalPage_AddProjectDocument } from '../generated/graphql-test'
const searchLabel = defaultMessages.globalPage.searchPlaceholder
const emptyMessages = defaultMessages.globalPage.empty
@@ -19,8 +19,42 @@ describe('<GlobalPage />', { viewportHeight: 900, viewportWidth: 1200 }, () => {
cy.findByText(emptyMessages.title).should('be.visible')
cy.findByText(emptyMessages.helper).should('be.visible')
// TODO: This should open a native file picker
const addProjectStub = cy.stub()
cy.stubMutationResolver(GlobalPage_AddProjectDocument, (defineResult) => {
addProjectStub()
return defineResult({
addProject: {
'projects': [
{
'id': '1',
'title': 'some-test-title',
'projectRoot': '/usr/local/dev/projects/some-test-title',
'__typename': 'GlobalProject',
},
{
'id': 'R2xvYmFsUHJvamVjdDoyOmFub3RoZXItdGVzdC1wcm9qZWN0',
'title': 'another-test-project',
'projectRoot': '/usr/local/dev/projects/another-test-project',
'__typename': 'GlobalProject',
},
],
'localSettings': {
'availableEditors': [],
'preferences': {
'preferredEditorBinary': null,
'__typename': 'LocalSettingsPreferences',
},
'__typename': 'LocalSettings',
},
'__typename': 'Query',
} })
})
cy.findByText(emptyMessages.browseManually).click()
cy.wrap(addProjectStub).should('have.been.called')
})
})
@@ -47,11 +81,14 @@ describe('<GlobalPage />', { viewportHeight: 900, viewportWidth: 1200 }, () => {
})
it('can add a project when clicking the button', () => {
cy.findByText('cypress-config-ts').should('not.exist')
cy.contains('button', defaultMessages.globalPage.addProjectButton).click()
cy.get('input[type=file]')
.attachFileWithPath('absolute/path/to/yet-another-test-project/cypress.config.ts')
.trigger('change', { force: true })
// .findByText('yet-another-test-project').should('be.visible')
cy.findByText('cypress-config-ts').should('be.visible')
})
})
})
-9
View File
@@ -22,15 +22,6 @@ app.use(createI18n())
let launchpadClient: Client
// TODO: (tim) remove this when we refactor to remove the retry plugin logic
export function getLaunchpadClient () {
if (!launchpadClient) {
throw new Error(`Cannot access launchpadClient before app has been init`)
}
return launchpadClient
}
// Make sure highlighter is initialized before
// we show any code to avoid jank at rendering
Promise.all([
@@ -138,11 +138,9 @@ const emits = defineEmits<{
const step1Modal = ref(false)
const step2Modal = ref(false)
// probably to be changed for a GQL field
const selectOption = ref<PossibleOption>()
function applySkipResult (val: PossibleOption) {
// TODO: add a GQL mutation here
selectOption.value = val
emits('selectOption', selectOption.value)
}
@@ -82,7 +82,7 @@ const toInstall = computed(() => {
return props.gql.wizard.packagesToInstall?.map((p) => p.package)
})
// TODO: convert this to a subscription
// TODO: UNIFY-1350 convert this to a subscription
const intervalQueryTrigger = useIntervalFn(async () => {
const res = await queryInstalled.executeQuery({ requestPolicy: 'network-only' })
@@ -10,6 +10,7 @@
:content="file.file.contents"
:status="file.status"
:file-path="file.file.relative"
:file-extension="file.file.fileExtension"
:description="file.description || undefined"
/>
<hr class="my-4">
@@ -64,6 +65,7 @@ fragment ScaffoldedFiles on Query {
absolute
relative
contents
fileExtension
}
}
}
@@ -81,6 +81,7 @@ const warnings = computed(() => {
const dismiss = (key) => {
// TODO, call a mutation here so that the server persists the result of the mutation.
// However, we still intend to keep the "warnings" dismissal so that the client updates immediately before the server responds.
// UNIFY-1368
dismissed.value[key] = true
}