Skip to content

Commit

Permalink
test(desk-tool): port document actions tests to playwright
Browse files Browse the repository at this point in the history
  • Loading branch information
vicmeow committed Feb 21, 2022
1 parent 515a752 commit fe2306d
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 10 deletions.
2 changes: 1 addition & 1 deletion dev/test-studio/parts/deskStructure.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const DEBUG_INPUT_TYPES = [
'withDocumentTest',
]

const CI_INPUT_TYPES = ['conditionalFieldset', 'validationCI']
const CI_INPUT_TYPES = ['conditionalFieldset', 'validationCI', 'documentActionsCI']
const FIELD_GROUP_TYPES = [
'fieldGroups',
'fieldGroupsDefault',
Expand Down
12 changes: 12 additions & 0 deletions dev/test-studio/schema/ci/documentActionsCI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default {
name: 'documentActionsCI',
title: 'Document Actions CI',
type: 'document',
fields: [
{
name: 'title',
title: 'Title',
type: 'string',
},
],
}
2 changes: 2 additions & 0 deletions dev/test-studio/schema/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import species from './species'
// CI documents
import conditionalFieldset from './ci/conditionalFieldset'
import validationTest from './ci/validationCI'
import documentActionsCI from './ci/documentActionsCI'

export default createSchema({
name: 'test-examples',
Expand Down Expand Up @@ -180,5 +181,6 @@ export default createSchema({
fieldGroupsDefault,
fieldGroupsMany,
fieldGroupsWithValidation,
documentActionsCI,
]),
})
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@
"@babel/preset-typescript": "^7.10.4",
"@babel/register": "^7.7.4",
"@babel/runtime": "7.12.13",
"@sanity/client": "^3.0.1",
"@cypress/code-coverage": "^3.9.12",
"@playwright/test": "^1.18.1",
"@playwright/test": "^1.19.1",
"@sanity/client": "^3.0.1",
"@types/jest": "^27.0.1",
"@types/node": "^14.18.9",
"@types/react": "^17.0.0",
Expand Down Expand Up @@ -140,5 +140,8 @@
"hooks": {
"commitmsg": "node scripts/validateCommitMessage.js"
}
},
"dependencies": {
"playright": "^0.0.22"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const ConfirmDelete = enhanceWithReferringDocuments(function ConfirmDelet
onClick={onConfirm}
text={hasReferringDocuments ? 'Delete anyway' : 'Delete now'}
tone="critical"
data-testid="confirm-delete"
/>
)}
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const ConfirmUnpublish = enhanceWithReferringDocuments(function ConfirmUn
onClick={onConfirm}
text={hasReferringDocuments ? 'Try to unpublish anyway' : 'Unpublish now'}
tone="critical"
data-testid="confirm-unpublish"
/>
)}
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@ export function PaneItem(props: PaneItemProps) {
pressed={pressed}
selected={selected || clicked}
tone="inherit"
data-testid={`pane-item-${id}`}
>
{preview}
</PreviewCard>
),
[clicked, handleClick, LinkComponent, pressed, preview, selected]
[clicked, handleClick, LinkComponent, pressed, preview, selected, id]
)
}
4 changes: 3 additions & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const config: PlaywrightTestConfig = {
testDir: './playwright/tests',
/* Maximum time one test can run for. */
// timeout: 30 * 1000 * 1000,
// Limit the number of failures on CI to save resources
maxFailures: process.env.CI ? 10 : undefined,

expect: {
/**
Expand Down Expand Up @@ -91,7 +93,7 @@ const config: PlaywrightTestConfig = {
],

/* Folder for test artifacts such as screenshots, videos, traces, etc. */
outputDir: 'test-results/',
outputDir: 'playwright/test-results/',

/* Run your local dev server before starting the tests */
// webServer: {
Expand Down
8 changes: 3 additions & 5 deletions playwright/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable no-process-env */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */

import {chromium, FullConfig} from '@playwright/test'

require('dotenv').config()
Expand All @@ -11,12 +7,13 @@ require('dotenv').config()
* are logged in for all tests
*/

async function globalSetup(config: FullConfig) {
async function globalSetup(config: FullConfig): Promise<void> {
const {baseURL} = config.projects[0].use
const browser = await chromium.launch()
// Create context to store our session token cookie in
const context = await browser.newContext()
const page = await context.newPage()
// eslint-disable-next-line no-process-env
const token = process.env.PLAYWRIGHT_SANITY_SESSION_TOKEN

if (!token) {
Expand All @@ -26,6 +23,7 @@ async function globalSetup(config: FullConfig) {
const [response] = await Promise.all([
page.waitForResponse('*/**/users/me*'),
// This action triggers the request
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
page.goto(baseURL!),
])

Expand Down
4 changes: 4 additions & 0 deletions playwright/helpers/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const DEFAULT_DATASET_NAME = 'test'
export const STUDIO_SPACE_NAME = 'test'
export const STUDIO_PROJECT_ID = 'ppsg7ml5'
export const STALE_TEST_THRESHOLD_MS = 10000
18 changes: 18 additions & 0 deletions playwright/helpers/createUniqueDocument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {SanityDocument, SanityDocumentStub} from '@sanity/client'
import {uuid} from '@sanity/uuid'
import {testSanityClient} from '.'

export async function createUniqueDocument({
_type,
_id,
...restProps
}: SanityDocumentStub): Promise<Partial<SanityDocument>> {
const doc = {
_type,
_id: _id || uuid(),
...restProps,
}

await testSanityClient.create(doc)
return doc
}
3 changes: 3 additions & 0 deletions playwright/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './sanityClient'
export * from './createUniqueDocument'
export * from './constants'
21 changes: 21 additions & 0 deletions playwright/helpers/sanityClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import sanityClient from '@sanity/client'
import {STALE_TEST_THRESHOLD_MS} from './constants'

export const testSanityClient = sanityClient({
projectId: 'ppsg7ml5',
dataset: 'test',
token: process.env.PLAYWRIGHT_SANITY_SESSION_TOKEN,
useCdn: false,
apiVersion: '2021-08-31',
})

export function deleteDocumentsForRun(
typeName: string,
runId: string
): {query: string; params: Record<string, unknown>} {
const threshold = new Date(Date.now() - STALE_TEST_THRESHOLD_MS).toISOString()
return {
query: `*[_type == $typeName && (runId == $runId || _createdAt < "${threshold}")]`,
params: {typeName, runId},
}
}
121 changes: 121 additions & 0 deletions playwright/tests/desk-tool/documentActions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {test, expect} from '@playwright/test'
import {uuid} from '@sanity/uuid'
import {
createUniqueDocument,
deleteDocumentsForRun,
STUDIO_SPACE_NAME,
testSanityClient,
} from '../../helpers'

/*
**NOTE**
In these tests, we are not testing input events, so to speed up the tests we will use use `page.fill()` instead of `page.type()` to populate the document title field
*/

const TITLE_PREFIX = '[playwright]'
const inputSelector = 'data-testid=input-title >> input'
const TEST_RUN_ID = uuid()

// The path of the network request we want to wait for
const documentActionPath = (action) =>
`*/**/mutate/${STUDIO_SPACE_NAME}?tag=sanity.studio.document.${action}*`

// Helper to generate path to document created in a test
const generateDocumentUri = (docId) =>
`/${STUDIO_SPACE_NAME}/desk/input-ci;documentActionsCI;${docId}`

// Helper to get the path to the document the client creates for a test
async function createDocument(
_type: string,
title?: string
): Promise<{studioPath: string; documentId: string}> {
const testDoc = await createUniqueDocument({runId: TEST_RUN_ID, _type, title})
return {studioPath: generateDocumentUri(testDoc?._id), documentId: testDoc?._id}
}

test.describe('@sanity/desk-tool: document actions', () => {
test.afterEach(async ({page}, testInfo) => {
// After each test, delete the created documents if the test passed
if (testInfo.status === testInfo.expectedStatus) {
await testSanityClient.delete(deleteDocumentsForRun('documentActionsCI', TEST_RUN_ID))
}
})

test('edit and publish document', async ({page}, testInfo) => {
const title = `${TITLE_PREFIX} ${testInfo.title}`
const publishButton = page.locator('data-testid=action-Publish')
const {studioPath} = await createDocument('documentActionsCI')
await page.goto(studioPath)
await page.fill(inputSelector, title)
expect(page.locator(inputSelector)).toHaveValue(title)
expect(publishButton).toBeEnabled()
expect(publishButton).toHaveAttribute('data-disabled', 'false')

await Promise.all([page.waitForResponse(documentActionPath('publish')), publishButton.click()])
await expect(publishButton).toBeDisabled()
await expect(publishButton).toHaveAttribute('data-disabled', 'true')
})

test('unpublish document', async ({page}, testInfo) => {
const title = `${TITLE_PREFIX} ${testInfo.title}`
const publishButton = page.locator('data-testid=action-Publish')

const {studioPath} = await createDocument('documentActionsCI', title)

await page.goto(studioPath)

expect(page.locator(inputSelector)).toHaveValue(title)
await expect(publishButton).toBeDisabled()
expect(publishButton).toHaveAttribute('data-disabled', 'true')
page.locator('data-testid=action-menu-button').click()
page.locator('data-testid=action-Unpublish').click()

await Promise.all([
page.waitForResponse(documentActionPath('unpublish')),
page.locator('data-testid=confirm-unpublish').click(),
])

await expect(publishButton).toBeEnabled()
await expect(publishButton).toHaveAttribute('data-disabled', 'false')
})

test('duplicate document', async ({page}, testInfo) => {
const title = `${TITLE_PREFIX} ${testInfo.title}`
const {studioPath} = await createDocument('documentActionsCI', title)

await page.goto(studioPath)

expect(page.locator(inputSelector)).toHaveValue(title)
page.locator('data-testid=action-menu-button').click()

await Promise.all([
page.waitForResponse(documentActionPath('duplicate')),
page.locator('data-testid=action-Duplicate').click(),
])
// Check if we are viewing a new document and not the one created for this test
await expect(page.url()).not.toMatch(`*${studioPath}`)
})

test('delete document', async ({page}, testInfo) => {
const title = `${TITLE_PREFIX} ${testInfo.title}`
const publishButton = page.locator('data-testid=action-Publish')

const {studioPath, documentId} = await createDocument('documentActionsCI', title)

await page.goto(studioPath)

expect(page.locator(inputSelector)).toHaveValue(title)
page.locator('data-testid=action-menu-button').click()
page.locator('data-testid=action-Delete').click()

await Promise.all([
page.waitForResponse(documentActionPath('delete')),
page.locator('data-testid=confirm-delete').click(),
])
await expect(publishButton).toBeDisabled()
await expect(publishButton).toHaveAttribute('data-disabled', 'true')
expect(
await page.locator(`data-testid=pane-content >> data-testid=pane-item-${documentId}`).count()
).toBe(0)
})
})

0 comments on commit fe2306d

Please sign in to comment.