Skip to content

Commit

Permalink
Dashboard Issues (#11685)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrFlashAccount authored Nov 27, 2024
1 parent 5d7e89b commit 88ba6fa
Show file tree
Hide file tree
Showing 37 changed files with 477 additions and 254 deletions.
1 change: 1 addition & 0 deletions app/common/src/text/english.json
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@
"assetDocs.notProject": "Please select a project to view its docs.",
"assetDocs.noDocs": "No docs available for this asset.",
"assetProperties.notSelected": "Select a single asset to view its properties.",
"assetProperties.localBackend": "Properties are not available for local assets.",
"assetVersions.localAssetsDoNotHaveVersions": "Local assets do not have versions.",
"assetVersions.notSelected": "Select a single asset to view its versions.",
"assetProjectSessions.noSessions": "No sessions yet! Open the project to start a session.",
Expand Down
2 changes: 2 additions & 0 deletions app/gui/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const sharedConfig: Partial<ReactStorybookConfig> = {
if (window.parent !== window) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__
}
document.documentElement.classList.add('macos')
</script>
${head}
`
Expand Down
9 changes: 9 additions & 0 deletions app/gui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@
user-scalable = no"
/>
<title>Enso %ENSO_IDE_VERSION%</title>

<script type="module">
import { platform } from '../common/src/detect.ts'

const currentPlatform = platform()

document.documentElement.setAttribute('data-version', '%ENSO_IDE_VERSION%')
document.documentElement.classList.add(currentPlatform.toLowerCase())
</script>
</head>
<body>
<div id="enso-spotlight" class="enso-spotlight"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ export default class DrivePageActions extends PageActions {
})
}

/** Show the Docs tab of the Asset Panel. */
toggleDocsAssetPanel() {
return this.step('Toggle docs asset panel', async (page) => {
await this.showAssetPanel()
await page.getByTestId('asset-panel-tab-docs').click()
})
}

/** Interact with the container element of the assets table. */
withAssetsTable(callback: baseActions.LocatorCallback) {
return this.step('Interact with drive table', async (page) => {
Expand Down
53 changes: 52 additions & 1 deletion app/gui/integration-test/dashboard/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,31 @@ import * as uniqueString from 'enso-common/src/utilities/uniqueString'

import * as actions from './actions'

import { readFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import LATEST_GITHUB_RELEASES from './latestGithubReleases.json' with { type: 'json' }

// =================
// === Constants ===
// =================

const __dirname = dirname(fileURLToPath(import.meta.url))

const MOCK_SVG = `
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<defs>
<pattern id="checkerboard" width="20" height="20" patternUnits="userSpaceOnUse">
<rect width="10" height="10" fill="white"/>
<rect x="10" y="0" width="10" height="10" fill="black"/>
<rect x="0" y="10" width="10" height="10" fill="black"/>
<rect x="10" y="10" width="10" height="10" fill="white"/>
</pattern>
</defs>
<rect width="100" height="100" fill="url(#checkerboard)"/>
</svg>
`

/** The HTTP status code representing a response with an empty body. */
const HTTP_STATUS_NO_CONTENT = 204
/** The HTTP status code representing a bad request. */
Expand Down Expand Up @@ -175,7 +194,17 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
description: null,
labels: [],
parentId: defaultDirectoryId,
permissions: [],
permissions: [
{
user: {
organizationId: defaultOrganizationId,
userId: defaultUserId,
name: defaultUsername,
email: defaultEmail,
},
permission: permissions.PermissionAction.own,
},
],
parentsPath: '',
virtualParentsPath: '',
},
Expand Down Expand Up @@ -983,6 +1012,7 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {

return json
})

await post(remoteBackendPaths.CREATE_DIRECTORY_PATH + '*', (_route, request) => {
const body: backend.CreateDirectoryRequestBody = request.postDataJSON()
const title = body.title
Expand Down Expand Up @@ -1011,6 +1041,27 @@ async function mockApiInternal({ page, setupAPI }: MockParams) {
return json
})

await get(remoteBackendPaths.getProjectContentPath(GLOB_PROJECT_ID), (route) => {
const content = readFileSync(join(__dirname, './mock/enso-demo.main'), 'utf8')

return route.fulfill({
body: content,
contentType: 'text/plain',
})
})

await get(remoteBackendPaths.getProjectAssetPath(GLOB_PROJECT_ID, '*'), (route) => {
return route.fulfill({
// This is a mock SVG image. Just a square with a black background.
body: '/mock/svg.svg',
contentType: 'text/plain',
})
})

await page.route('mock/svg.svg', (route) => {
return route.fulfill({ body: MOCK_SVG, contentType: 'image/svg+xml' })
})

await page.route('*', async (route) => {
if (!isOnline) {
await route.abort('connectionfailed')
Expand Down
33 changes: 24 additions & 9 deletions app/gui/integration-test/dashboard/assetPanel.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @file Tests for the asset panel. */
import * as test from '@playwright/test'
import { expect, test } from '@playwright/test'

import * as backend from '#/services/Backend'

Expand All @@ -22,19 +22,18 @@ const EMAIL = '[email protected]'
// === Tests ===
// =============

test.test('open and close asset panel', ({ page }) =>
test('open and close asset panel', ({ page }) =>
actions
.mockAllAndLogin({ page })
.withAssetPanel(async (assetPanel) => {
await test.expect(assetPanel).toBeVisible()
await expect(assetPanel).toBeVisible()
})
.toggleAssetPanel()
.withAssetPanel(async (assetPanel) => {
await test.expect(assetPanel).not.toBeVisible()
}),
)
await expect(assetPanel).not.toBeVisible()
}))

test.test('asset panel contents', ({ page }) =>
test('asset panel contents', ({ page }) =>
actions
.mockAllAndLogin({
page,
Expand Down Expand Up @@ -64,5 +63,21 @@ test.test('asset panel contents', ({ page }) =>
// `getByText` is required so that this assertion works if there are multiple permissions.
// This is not visible; "Shared with" should only be visible on the Enterprise plan.
// await test.expect(actions.locateAssetPanelPermissions(page).getByText(USERNAME)).toBeVisible()
}),
)
}))

test('Asset Panel Documentation view', ({ page }) => {
return actions
.mockAllAndLogin({
page,
setupAPI: (api) => {
api.addProject('project', { description: DESCRIPTION })
},
})
.driveTable.clickRow(0)
.toggleDocsAssetPanel()
.withAssetPanel(async (assetPanel) => {
await expect(assetPanel.getByTestId('asset-panel-tab-panel-docs')).toBeVisible()
await expect(assetPanel.getByTestId('asset-docs-content')).toBeVisible()
await expect(assetPanel.getByTestId('asset-docs-content')).toHaveText(/Project Goal/)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test.test('extra columns should stick to right side of assets table', ({ page })
const assetsTableRight = await assetsTable.evaluate(
(element) => element.getBoundingClientRect().right,
)
test.expect(extraColumnsRight).toEqual(assetsTableRight)
test.expect(extraColumnsRight).toEqual(assetsTableRight - 12)
})
.toPass({ timeout: PASS_TIMEOUT })
}),
Expand Down Expand Up @@ -72,9 +72,9 @@ test.test('extra columns should stick to top of scroll container', async ({ page
) {
scrollableParent = scrollableParent.parentElement
}
return scrollableParent?.getBoundingClientRect().top
return scrollableParent?.getBoundingClientRect().top ?? 0
})
test.expect(extraColumnsTop).toEqual(assetsTableTop)
test.expect(extraColumnsTop).toEqual(assetsTableTop + 2)
})
.toPass({ timeout: PASS_TIMEOUT })
})
Expand Down
22 changes: 4 additions & 18 deletions app/gui/integration-test/dashboard/auth.setup.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,15 @@
import { test as setup } from '@playwright/test'
import { existsSync } from 'node:fs'
import path from 'node:path'
import * as actions from './actions'

const __dirname = path.dirname(new URL(import.meta.url).pathname)
const authFile = path.join(__dirname, '../../playwright/.auth/user.json')
const isProd = process.env.NODE_ENV === 'production'

const isFileExists = () => {
if (isProd) {
return false
}

return existsSync(authFile)
}

setup('authenticate', ({ page }) => {
if (isFileExists()) {
return setup.skip()
}

return actions
setup('authenticate', ({ page }) =>
actions
.mockAll({ page })
.login()
.do(async () => {
await page.context().storageState({ path: authFile })
})
})
}),
)
59 changes: 50 additions & 9 deletions app/gui/integration-test/dashboard/editAssetName.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/** @file Test copying, moving, cutting and pasting. */
import * as test from '@playwright/test'
import { test } from '@playwright/test'

import * as actions from './actions'

test.test.beforeEach(({ page }) => actions.mockAllAndLogin({ page }))

test.test('edit name', async ({ page }) => {
test('edit name (double click)', async ({ page }) => {
await actions.mockAllAndLogin({ page })
const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz'
Expand All @@ -18,7 +17,41 @@ test.test('edit name', async ({ page }) => {
await test.expect(row).toHaveText(new RegExp('^' + newName))
})

test.test('edit name (keyboard)', async ({ page }) => {
test('edit name (context menu)', async ({ page }) => {
await actions.mockAllAndLogin({
page,
setupAPI: (api) => {
api.addAsset(api.createDirectory('foo'))
},
})

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz'

await actions.locateAssetRowName(row).click({ button: 'right' })
await actions
.locateContextMenus(page)
.getByText(/Rename/)
.click()

const input = page.getByTestId('asset-row-name')

await test.expect(input).toBeVisible()
await test.expect(input).toBeFocused()

await input.fill(newName)

await test.expect(input).toHaveValue(newName)

await input.press('Enter')

await test.expect(row).toHaveText(new RegExp('^' + newName))
})

test('edit name (keyboard)', async ({ page }) => {
await actions.mockAllAndLogin({ page })

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz quux'
Expand All @@ -31,7 +64,9 @@ test.test('edit name (keyboard)', async ({ page }) => {
await test.expect(row).toHaveText(new RegExp('^' + newName))
})

test.test('cancel editing name', async ({ page }) => {
test('cancel editing name (double click)', async ({ page }) => {
await actions.mockAllAndLogin({ page })

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz'
Expand All @@ -46,7 +81,9 @@ test.test('cancel editing name', async ({ page }) => {
await test.expect(row).toHaveText(new RegExp('^' + oldName))
})

test.test('cancel editing name (keyboard)', async ({ page }) => {
test('cancel editing name (keyboard)', async ({ page }) => {
await actions.mockAllAndLogin({ page })

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)
const newName = 'foo bar baz quux'
Expand All @@ -60,7 +97,9 @@ test.test('cancel editing name (keyboard)', async ({ page }) => {
await test.expect(row).toHaveText(new RegExp('^' + oldName))
})

test.test('change to blank name', async ({ page }) => {
test('change to blank name (double click)', async ({ page }) => {
await actions.mockAllAndLogin({ page })

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)

Expand All @@ -74,7 +113,9 @@ test.test('change to blank name', async ({ page }) => {
await test.expect(row).toHaveText(new RegExp('^' + oldName))
})

test.test('change to blank name (keyboard)', async ({ page }) => {
test('change to blank name (keyboard)', async ({ page }) => {
await actions.mockAllAndLogin({ page })

const assetRows = actions.locateAssetRows(page)
const row = assetRows.nth(0)

Expand Down
Loading

0 comments on commit 88ba6fa

Please sign in to comment.