-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into column-sort-arrows
- Loading branch information
Showing
17 changed files
with
1,017 additions
and
44,694 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
name: Playwright Tests | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
name: 🧪 ${{ matrix.project }} E2E Tests | ||
runs-on: ${{ matrix.os }} | ||
timeout-minutes: 20 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- project: chromium | ||
os: ubuntu-latest | ||
cache_dir: ~/.cache/ms-playwright | ||
|
||
- project: firefox | ||
os: ubuntu-latest | ||
cache_dir: ~/.cache/ms-playwright | ||
|
||
- project: webkit | ||
os: macos-14 | ||
cache_dir: ~/Library/Caches/ms-playwright | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: lts/* | ||
cache: "yarn" | ||
|
||
- name: Install dependencies | ||
run: yarn install --immutable | ||
|
||
- name: Write out playwright version | ||
run: yarn --silent playwright --version > .playwright-version | ||
|
||
- name: ⚡️ Cache playwright binaries | ||
uses: actions/cache@v3 | ||
id: playwright-cache | ||
with: | ||
path: ${{ matrix.cache_dir }} | ||
key: ${{ runner.os }}-${{ matrix.project }}-pw-${{ hashFiles('**/.playwright-version') }} | ||
|
||
- name: Install Playwright Browsers | ||
if: steps.playwright-cache.outputs.cache-hit != 'true' | ||
run: yarn playwright install --with-deps ${{ matrix.project }} | ||
|
||
- name: Run yarn build | ||
run: yarn build | ||
|
||
- name: Run Playwright tests | ||
run: yarn test --project=${{ matrix.project }} | ||
|
||
- name: Upload test results | ||
if: failure() | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: playwright-report | ||
path: playwright-report |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* eslint-disable testing-library/prefer-screen-queries */ | ||
import { test, expect } from '@playwright/test'; | ||
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json'; | ||
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json'; | ||
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json'; | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.route('*/**/api/**', async (route) => { | ||
const url = route.request().url(); | ||
let json; | ||
|
||
if (url) { | ||
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) { | ||
json = mockData; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) { | ||
json = mockAnnotations; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('alttxt')) { | ||
json = mockAltText; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) { | ||
await route.fulfill({ status: 200 }); | ||
} else { | ||
await route.continue(); | ||
} | ||
} else { | ||
await route.abort(); | ||
} | ||
}); | ||
}); | ||
|
||
test('Alt Text', async ({ page }) => { | ||
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193'); | ||
|
||
const altTextSidebarButton = await page.getByLabel('Open alt text sidebar'); | ||
await expect(altTextSidebarButton).toBeVisible(); | ||
await altTextSidebarButton.click(); | ||
|
||
const altTextSidebar = await page.getByLabel('Alt Text Sidebar', { exact: true }); | ||
await expect(altTextSidebar).toBeVisible(); | ||
|
||
const altTextHeading = await page.getByRole('heading', { name: 'Alt Text' }); | ||
await expect(altTextHeading).toBeVisible(); | ||
|
||
/// ///////////////// | ||
// Plot Information | ||
/// ///////////////// | ||
const plotInformation = await page.getByRole('button', { name: 'Plot Information' }); | ||
await expect(plotInformation).toBeVisible(); | ||
await plotInformation.click(); | ||
|
||
const editPlotInformationButton = await page.getByLabel('Toggle editable descriptions'); | ||
await expect(editPlotInformationButton).toBeVisible(); | ||
await editPlotInformationButton.click(); | ||
|
||
const datasetDescriptionInput = await page.getByPlaceholder('eg: movie genres and ratings'); | ||
await expect(datasetDescriptionInput).toBeVisible(); | ||
await expect(datasetDescriptionInput).toBeEditable(); | ||
await datasetDescriptionInput.click(); | ||
await datasetDescriptionInput.fill('Test dataset description'); | ||
|
||
const setsInput = await page.getByPlaceholder('eg: movie genres (dataset'); | ||
await expect(setsInput).toBeVisible(); | ||
await expect(setsInput).toBeEditable(); | ||
await setsInput.click(); | ||
await setsInput.fill('Test sets value'); | ||
|
||
const itemsInput = await page.getByPlaceholder('eg: movies (dataset rows)'); | ||
await expect(itemsInput).toBeVisible(); | ||
await expect(itemsInput).toBeEditable(); | ||
await itemsInput.click(); | ||
await itemsInput.fill('Test items value'); | ||
|
||
const plotInformationOutput = await page.getByText('This UpSet plot shows test'); | ||
await expect(plotInformationOutput).toBeVisible(); | ||
await expect(plotInformationOutput).toHaveText('This UpSet plot shows Test dataset description. The sets are Test sets value. The items are Test items value.'); | ||
|
||
await page.getByRole('button', { name: 'Save' }).click(); | ||
await plotInformation.click(); | ||
|
||
/// ///////////////// | ||
// Alt Text Output | ||
/// ///////////////// | ||
const UpSetIntroduction = { | ||
heading: await page.getByRole('heading', { name: 'UpSet Introduction' }), | ||
content: await page.getByText('This is an UpSet plot that'), | ||
}; | ||
await expect(UpSetIntroduction.heading).toBeVisible(); | ||
await expect(UpSetIntroduction.content).toBeVisible(); | ||
await expect(UpSetIntroduction.content).toHaveText('This is an UpSet plot that visualizes set intersection. To learn about UpSet plots, visit https://upset.app.'); | ||
|
||
const datasetProperties = { | ||
heading: await page.getByRole('heading', { name: 'Dataset Properties' }), | ||
content: await page.getByText('The dataset contains 6 sets'), | ||
}; | ||
|
||
await expect(datasetProperties.heading).toBeVisible(); | ||
await expect(datasetProperties.content).toBeVisible(); | ||
await expect(datasetProperties.content).toHaveText('The dataset contains 6 sets, and 44 elements, of which 6 are shown in the plot.'); | ||
|
||
const setProperties = { | ||
heading: await page.getByRole('heading', { name: 'Set Properties', exact: true }), | ||
content: await page.getByText('The largest set is Male with'), | ||
}; | ||
await expect(setProperties.heading).toBeVisible(); | ||
await expect(setProperties.content).toBeVisible(); | ||
await expect(setProperties.content).toHaveText('The largest set is Male with 18 elements, followed by School with 6, Duff Fan with 6, Evil with 6, Power Plant with 5, and Blue Hair with 3.'); | ||
|
||
const intersectionProperties = { | ||
heading: await page.getByRole('heading', { name: 'Intersection Properties' }), | ||
content: await page.getByText('The plot is sorted by size.'), | ||
}; | ||
await expect(intersectionProperties.heading).toBeVisible(); | ||
await expect(intersectionProperties.content).toBeVisible(); | ||
await expect(intersectionProperties.content).toHaveText('The plot is sorted by size. There are 12 non-empty intersections, all of which are shown in the plot. The largest 5 intersections are School Male (3), the empty intersection (3), Just Male (3), Duff_Fan Male Power_Plant (3), and Evil Male (2).'); | ||
|
||
const statisticalInformation = { | ||
heading: await page.getByRole('heading', { name: 'Statistical Information' }), | ||
content: await page.getByText('The average intersection size'), | ||
}; | ||
await expect(statisticalInformation.heading).toBeVisible(); | ||
await expect(statisticalInformation.content).toBeVisible(); | ||
await expect(statisticalInformation.content).toHaveText('The average intersection size is 2, and the median is 2. The 90th percentile is 3, and the 10th percentile is 1. The largest set, Male, is present in 75.0% of all non-empty intersections. The smallest set, Blue Hair, is present in 0.0% of all non-empty intersections.'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* eslint-disable testing-library/prefer-screen-queries */ | ||
import { test, expect } from '@playwright/test'; | ||
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json'; | ||
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json'; | ||
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json'; | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.route('*/**/api/**', async (route) => { | ||
const url = route.request().url(); | ||
let json; | ||
|
||
if (url) { | ||
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) { | ||
json = mockData; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) { | ||
json = mockAnnotations; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('alttxt')) { | ||
json = mockAltText; | ||
await route.fulfill({ json }); | ||
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) { | ||
await route.fulfill({ status: 200 }); | ||
} else { | ||
await route.continue(); | ||
} | ||
} else { | ||
await route.abort(); | ||
} | ||
}); | ||
}); | ||
|
||
test('Datatable', async ({ page }) => { | ||
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193'); | ||
|
||
// ////////////////// | ||
// Open the datatable | ||
// ////////////////// | ||
const page1Promise = page.waitForEvent('popup'); | ||
await page.getByRole('button', { name: 'Data Table' }).click(); | ||
|
||
// ////////////////// | ||
// Test downloads | ||
// ////////////////// | ||
const page1 = await page1Promise; | ||
const heading1 = await page1.getByRole('heading', { name: 'UpSet Data Table' }); | ||
await expect(heading1).toBeVisible(); | ||
|
||
const downloadPromise = page1.waitForEvent('download'); | ||
const downloadButton = await page1.locator('div').filter({ hasText: /^UpSet Data TableDownload$/ }).getByRole('button'); | ||
await expect(downloadButton).toBeVisible(); | ||
await downloadButton.click(); | ||
const download = await downloadPromise; | ||
await expect(download).not.toBeNull(); | ||
|
||
const heading2 = await page1.getByRole('heading', { name: 'Visible Sets' }); | ||
await expect(heading2).toBeVisible(); | ||
const download2Promise = page1.waitForEvent('download'); | ||
const downloadButton2 = await page1.locator('div').filter({ hasText: /^Visible SetsDownload$/ }).getByRole('button'); | ||
await expect(downloadButton2).toBeVisible(); | ||
await downloadButton2.click(); | ||
const download2 = await download2Promise; | ||
await expect(download2).not.toBeNull(); | ||
|
||
// there is no download event because there are no hidden sets in this dataset | ||
const heading3 = await page1.getByRole('heading', { name: 'Hidden Sets' }); | ||
await expect(heading3).toBeVisible(); | ||
|
||
const downloadButton3 = await page1.locator('div').filter({ hasText: /^Hidden SetsDownload$/ }).getByRole('button'); | ||
await expect(downloadButton3).toBeVisible(); | ||
|
||
// ////////////////// | ||
// Test that the tables exist | ||
// ////////////////// | ||
const datatable = await page1.getByText('IntersectionSizeSchool Male3Unincluded3Just Male3Duff_Fan Male Power_Plant3Evil Male2Evil Male Power_Plant2Duff_Fan Male2Just Blue_Hair2Just School1School Evil Male1Rows per page:101–10 of'); | ||
await expect(datatable).toBeVisible(); | ||
const visibleSets = await page1.getByText('SetSizeSchool6Blue_Hair3Duff_Fan6Evil6Male18Power_Plant5Rows per page:101–6 of'); | ||
await expect(visibleSets).toBeVisible(); | ||
const hiddenSets = await page1.getByText('No rowsSetSizeRows per page:100–0 of'); | ||
await expect(hiddenSets).toBeVisible(); | ||
}); |
Oops, something went wrong.