Skip to content

Commit

Permalink
Merge pull request #1280 from jplag/report-viewer/simple-e2e
Browse files Browse the repository at this point in the history
Some small e2e tests for report viewer
  • Loading branch information
sebinside authored Jan 22, 2024
2 parents 3c9af11 + 3483eaa commit 426b2a1
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 13 deletions.
24 changes: 21 additions & 3 deletions .github/workflows/report-viewer-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,27 @@ jobs:
with:
node-version: "18"

- name: Install and Test 🧪
- name: Install and Build 🔧
working-directory: report-viewer
run: |
npm install
npx playwright install --with-deps
npm run test:e2e
npm run build
- name: Install playwright 🔧
working-directory: report-viewer
run: npx playwright install --with-deps

- name: Run tests 🧪
working-directory: report-viewer
run: |
npm run test:e2e
- name: Upload test results 📤
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: |
report-viewer/test-results
report-viewer/playwright-report
retention-days: 30
13 changes: 8 additions & 5 deletions report-viewer/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const config: PlaywrightTestConfig = {
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
timeout: 5000,
toMatchSnapshot: {
maxDiffPixelRatio: 0.01
}
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
Expand All @@ -34,13 +37,13 @@ const config: PlaywrightTestConfig = {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:5173',
baseURL: 'http://localhost:8080',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',

/* Only on CI systems run the tests headless */
headless: !!process.env.CI
headless: true
},

/* Configure projects for major browsers */
Expand Down Expand Up @@ -103,8 +106,8 @@ const config: PlaywrightTestConfig = {
* Use the preview server on CI for more realistic testing.
Playwright will re-use the local server if there is already a dev-server running.
*/
command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
port: 5173,
command: 'vite preview --port 8080',
port: 8080,
reuseExistingServer: !process.env.CI
}
}
Expand Down
51 changes: 51 additions & 0 deletions report-viewer/tests/e2e/Cluster.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { test, expect } from '@playwright/test'
import { uploadFile } from './TestUtils'

test('Test cluster view', async ({ page }) => {
await page.goto('/')

await uploadFile('result_small_cluster.zip', page)

// check for all clusters being shown
expect(await page.getByText('submissions in cluster').all()).toHaveLength(6)

await page.getByText('4 94.75%').first().click()
await page.waitForURL(/\/cluster\/.*/)

// check that the cluster graph exist
expect(page.locator('canvas').first()).not.toBeHidden()

// switch to cluster chart
await page.getByText('Radar').first().click()

// Check cluster diagram
await page.waitForTimeout(3000)
const radarChart = page.locator('canvas').first()
expect(page.getByRole('combobox').first()).toHaveValue('C')
const clusterImageC = radarChart.screenshot()
await page.getByRole('combobox').selectOption('B')
expect(page.getByRole('combobox').first()).toHaveValue('B')
expect(await radarChart.screenshot()).not.toEqual(clusterImageC)

// Check comparison table
const comparisonTable = await page.textContent('body')
compareTableRow(comparisonTable, 1, 'C', 'A', 99.6, 99.6)
compareTableRow(comparisonTable, 2, 'D', 'C', 76.06, 95.93)
compareTableRow(comparisonTable, 3, 'D', 'A', 76.06, 95.93)
compareTableRow(comparisonTable, 4, 'B', 'D', 28.32, 80.85)
compareTableRow(comparisonTable, 5, 'B', 'C', 23.78, 97.16)
compareTableRow(comparisonTable, 6, 'B', 'A', 23.78, 97.16)
})

function compareTableRow(
table: string,
row: number,
id1: string,
id2: string,
similarityAVG: number,
similarityMAX: number
) {
expect(table).toContain(
`${row}${id1}${id2}${similarityAVG.toFixed(2)}% ${similarityMAX.toFixed(2)}%`
)
}
73 changes: 73 additions & 0 deletions report-viewer/tests/e2e/Comparison.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { test, expect, Page } from '@playwright/test'
import { uploadFile } from './TestUtils'

test('Test comparison table and comparsion view', async ({ page }) => {
await page.goto('/')

await uploadFile('result_small_cluster.zip', page)

const comparisonContainer = page.getByText(
'Top Comparisons: Type in the name of a submission to only show comparisons that contain this submission. Fully written out names get unhidden.Hide AllSort By'
)

// check for elements in average similarity table
const comparisonTableAverageSorted = await page.getByText('Cluster1').textContent()
expect(comparisonTableAverageSorted).toContain('1CA')
expect(comparisonTableAverageSorted).toContain('2DC')

await comparisonContainer.getByText('Maximum Similarity', { exact: true }).click()
// check for elements in maximum similarity table
const comparisonTableMaxSorted = await page.getByText('Cluster1').textContent()
expect(comparisonTableMaxSorted).toContain('1CA')
expect(comparisonTableMaxSorted).toContain('2BC')

await page.getByText('Hide All').click()
// check for elements being hidden
const comparisonTableOverviewHidden = await page.getByText('Cluster1').textContent()
expect(comparisonTableOverviewHidden).toMatch(/1anon[0-9]+anon[0-9]+/)
expect(comparisonTableOverviewHidden).toMatch(/3anon[0-9]+anon[0-9]+/)
expect(comparisonTableOverviewHidden).toMatch(/4anon[0-9]+anon[0-9]+/)

await page.getByPlaceholder('Filter/Unhide Comparisons').fill('A')
// check for elements being unhidden and filtered
const comparisonTableOverviewFilteredA = await page.getByText('Cluster1').textContent()
expect(comparisonTableOverviewFilteredA).toMatch(/1anon[0-9]+A/) //toContain('1HiddenA')
expect(comparisonTableOverviewFilteredA).toMatch(/3anon[0-9]+A/)
// we cant check for 4Hidden because the dynamic scroller just moves it of screen, so the text is still there but not visible

await page.getByPlaceholder('Filter/Unhide Comparisons').fill('A C')
// check for elements being unhidden and filtered
const comparisonTableOverviewFilteredAC = await page.getByText('Cluster1').textContent()
expect(comparisonTableOverviewFilteredAC).toContain('1CA')
expect(comparisonTableOverviewFilteredAC).toMatch(/3anon[0-9]+A/)
expect(comparisonTableOverviewFilteredAC).toMatch(/4anon[0-9]+C/)

// go to comparison page
await page.getByText('1C').click()
await page.waitForURL(/\/comparison\/.*/)

// check for elements in comparison page
const bodyComparison = await page.locator('body').textContent()
expect(bodyComparison).toContain('Average Similarity: 99.59%')
expect(bodyComparison).toContain('GSTiling.java - GSTiling.java: 308')
expect(bodyComparison).toContain('Matches.java - Matches.java: 58')
expect(bodyComparison).toContain('A/Match.java')
expect(bodyComparison).toContain('C/Match.java')

// check for being able to hide and unhide elements
expect(await isCodeVisible(page, 'public class Match {')).toBe(false)
await page.getByText('A/Match.java').click()
expect(await isCodeVisible(page, 'public class Match {')).toBe(true)
await page.getByText('A/Match.java').click()
expect(await isCodeVisible(page, 'public class Match {')).toBe(false)

// unhide elements by clicking match list
expect(await isCodeVisible(page, 'public class GSTiling')).toBe(false)
await page.getByText('GSTiling.java - GSTiling.java: 308').click()
await page.waitForTimeout(1000)
expect(await isCodeVisible(page, 'public class GSTiling')).toBe(true)
})

async function isCodeVisible(page: Page, codePart: string) {
return await page.locator('pre', { hasText: codePart }).first().isVisible()
}
52 changes: 52 additions & 0 deletions report-viewer/tests/e2e/Distribution.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { test, expect, Page } from '@playwright/test'
import { uploadFile } from './TestUtils'

test('Test distribution diagram', async ({ page }) => {
await page.goto('/')

await uploadFile('result_small_cluster.zip', page)

const options = getTestCombinations()
selectOptions(page, options[0])
const canvas = page.locator('canvas').first()
let lastImage = await canvas.screenshot()
for (const option of options.slice(1)) {
await selectOptions(page, option)
const newImage = await canvas.screenshot()
expect(newImage).not.toEqual(lastImage)
lastImage = newImage
}
})

/**
* Checks if the distribution diagram is correct for the given options
* @param page Page currently tested on
* @param options Options to be selected
*/
async function selectOptions(page: Page, options: string[]) {
const distributionDiagramContainer = page.getByText('Distribution of Comparisons:Options:')
for (const option of options) {
await distributionDiagramContainer.getByText(option).first().click()
}
// This timeout is so that the screenshot is taken after the animation is finished
await page.waitForTimeout(3000)
}

function getTestCombinations() {
const options = [
['Average', 'Maximum'],
['Linear', 'Logarithmic']
]

const combinations: string[][] = []

const baseOptions = options.map((o) => o[0])
for (let i = 0; i < options.length; i++) {
for (let j = 0; j < options[i].length; j++) {
const combination = Array.from(baseOptions)
combination[i] = options[i][j]
combinations.push(combination)
}
}
return combinations
}
34 changes: 34 additions & 0 deletions report-viewer/tests/e2e/Information.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect, test } from '@playwright/test'
import { uploadFile } from './TestUtils'

test('Test information page', async ({ page }) => {
await page.goto('/')
await uploadFile('result_small_cluster.zip', page)

// check displayed information on overview page
const bodyOverview = await page.locator('body').textContent()
expect(bodyOverview).toContain('Directory: files')
expect(bodyOverview).toContain('Total Submissions: 4')
expect(bodyOverview).toContain('Total Comparisons: 6')
expect(bodyOverview).toContain('Min Token Match: 9')

// go to information page
await page.getByText('More', { exact: true }).click()
await page.waitForURL('/info')

// check displayed run options on information page
const runOptions = await page.getByText('Run Options:Submission Directory:').textContent()
expect(runOptions).toContain('Submission Directory: files')
expect(runOptions).toContain('Basecode Directory:')
expect(runOptions).toContain('Language: Javac based AST plugin')
expect(runOptions).toContain('File Extentions: .java, .JAVA')
expect(runOptions).toContain('Min Token Match: 9')

const runData = await page.getByText('Run Data:Date of Execution:').textContent()
expect(runData).toContain('Date of Execution: 02/09/23')
expect(runData).toContain('Execution Duration: 12 ms')
expect(runData).toContain('Total Submissions: 4')
expect(runData).toContain('Total Comparisons: 6')
expect(runData).toContain('Shown Comparisons: 6')
expect(runData).toContain('Missing Comparisons: 0')
})
19 changes: 19 additions & 0 deletions report-viewer/tests/e2e/TestUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Page, expect } from '@playwright/test'

/**
* Selects a file in the file chooser and uploads it.
* Expects the file to be in the tests/e2e/assets folder.
* Expects to be on the file upload page.
* @param fileName
*/
export async function uploadFile(fileName: string, page: Page) {
expect(page).toHaveURL('/')

// upload file through file chooser
const fileChooserPromise = page.waitForEvent('filechooser')
await page.getByText('Drag and Drop zip/Json file on this page').click()
const fileChooser = await fileChooserPromise
await fileChooser.setFiles(`tests/e2e/assets/${fileName}`)

await page.waitForURL('/overview')
}
Binary file not shown.
5 changes: 0 additions & 5 deletions report-viewer/tests/e2e/boilerplate.spec.ts

This file was deleted.

0 comments on commit 426b2a1

Please sign in to comment.