From 1328d787f39807279ea0c3e8d7e3f1b902f46449 Mon Sep 17 00:00:00 2001 From: Nate Lanza Date: Tue, 2 Apr 2024 14:08:43 -0600 Subject: [PATCH 1/5] Ensure size scale adjusts on re-render --- packages/upset/src/components/Header/SizeHeader.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/upset/src/components/Header/SizeHeader.tsx b/packages/upset/src/components/Header/SizeHeader.tsx index 3dab0524..8ccbcb11 100644 --- a/packages/upset/src/components/Header/SizeHeader.tsx +++ b/packages/upset/src/components/Header/SizeHeader.tsx @@ -16,6 +16,7 @@ import { Axis } from '../custom/Axis'; import { ProvenanceContext } from '../Root'; import { contextMenuAtom } from '../../atoms/contextMenuAtom'; import { HeaderSortArrow } from '../custom/HeaderSortArrow'; +import { visibleSetSelector } from '../../atoms/config/visibleSetsAtoms'; /** @jsxImportSource @emotion/react */ const hide = css` @@ -100,8 +101,12 @@ export const SizeHeader: FC = () => { ); }; + /** + * Updates the scale of the header based on the largest subset as long as the advanced scale slider hasn't taken + * control and set a value + */ useEffect(() => { - if (maxC !== -1) return; + if (advancedScale) return; const subs = Object.values(subsets.values); if (subs.length === 0) return; From af944d889885b7527a96adf22c5f1670bb5e6907 Mon Sep 17 00:00:00 2001 From: Nate Lanza Date: Tue, 2 Apr 2024 15:17:54 -0600 Subject: [PATCH 2/5] Docs & advanced scale bugfix --- packages/upset/src/atoms/maxSizeAtom.ts | 4 ++++ packages/upset/src/components/Header/SizeHeader.tsx | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/upset/src/atoms/maxSizeAtom.ts b/packages/upset/src/atoms/maxSizeAtom.ts index d1d4b70f..1bb0d84a 100644 --- a/packages/upset/src/atoms/maxSizeAtom.ts +++ b/packages/upset/src/atoms/maxSizeAtom.ts @@ -1,5 +1,9 @@ import { atom } from 'recoil'; +/** + * Max set size; used to set the size scale + * Either calculated automatically or manually set by the advanced scale slider + */ export const maxSize = atom({ key: 'max-size', default: -1, diff --git a/packages/upset/src/components/Header/SizeHeader.tsx b/packages/upset/src/components/Header/SizeHeader.tsx index 8ccbcb11..6239653e 100644 --- a/packages/upset/src/components/Header/SizeHeader.tsx +++ b/packages/upset/src/components/Header/SizeHeader.tsx @@ -16,7 +16,6 @@ import { Axis } from '../custom/Axis'; import { ProvenanceContext } from '../Root'; import { contextMenuAtom } from '../../atoms/contextMenuAtom'; import { HeaderSortArrow } from '../custom/HeaderSortArrow'; -import { visibleSetSelector } from '../../atoms/config/visibleSetsAtoms'; /** @jsxImportSource @emotion/react */ const hide = css` @@ -113,7 +112,7 @@ export const SizeHeader: FC = () => { const sizes = subs.map((s) => s.size); const maxS = Math.max(...sizes); setMaxSize(maxS); - }, [subsets, maxSize]); + }, [subsets, maxSize, advancedScale]); const globalScale = useScale([0, itemCount], [0, dimensions.attribute.width]); From f22bc63bb47482b24abd28a7de5201ac45b0d7ec Mon Sep 17 00:00:00 2001 From: Nate Lanza Date: Tue, 2 Apr 2024 15:18:05 -0600 Subject: [PATCH 3/5] Test for size header --- e2e-tests/plot.spec.ts | 98 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 e2e-tests/plot.spec.ts diff --git a/e2e-tests/plot.spec.ts b/e2e-tests/plot.spec.ts new file mode 100644 index 00000000..6db387ae --- /dev/null +++ b/e2e-tests/plot.spec.ts @@ -0,0 +1,98 @@ +/* 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(); + } + }); +}); + +/** + * Toggles the advanced scale slider. Must be awaited + * @param page page provided to test function + */ +async function toggleAdvancedScale(page) { + await page.getByText('Size', { exact: true }).click({ + button: 'right' + }); + await page.getByRole('menuitem', { name: 'Toggle Advanced Scale' }).click(); +} + +/** + * Removes a visible set by name. Must be awaited + * @param page page provided to test + * @param setName name of set + */ +async function removeSetByName(page, setName: string) { + await page.locator('p').filter({ hasText: new RegExp('^' + setName + '$') }).click({ button: 'right' }); + await page.getByRole('menuitem', { name: 'Remove Set: ' + setName }).click(); +} + +/** + * Adds an invisible set by name. Must be awaited + * @param page page provided to test + * @param setName name of set + */ +async function addSetByName(page, setName: string) { + await page.getByText(setName, { exact: true }).click({ + button: 'right' + }); + await page.getByRole('menuitem', { name: 'Add Set: ' + setName }).click(); +} + +/** + * Tests that the size header resizes when sets are added/removed and the advanced scale slider works + */ +test('Size header', async ({ page }) => { + await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193'); + + // Ensure that the scale increases when necessary upon set removal + await expect(page.locator('g').filter({ hasText: /^33$/ }).locator('text').nth(1)).toBeVisible(); + await removeSetByName(page, 'Blue Hair'); + await expect(page.getByText('5', { exact: true }).nth(1)).toBeVisible(); + + // Ensure that the scale decreases when necessary upon set removal + await removeSetByName(page, 'Male'); + await expect(page.getByText('8', { exact: true }).nth(1)).toBeVisible(); + + // Ensure that the scale updates upon set addition + await addSetByName(page, 'Male'); + await expect(page.getByText('5', { exact: true }).nth(1)).toBeVisible(); + + // Ensure that dragging the advanced slider works + await toggleAdvancedScale(page); + await page.locator('g').filter({ hasText: /^0055101015152020Size001122334455$/ }).locator('rect').nth(1). + dragTo(page.getByText('15', { exact: true }).nth(1)); + await expect(page.getByText('15').nth(3)).toBeVisible(); + + // Ensure that adding sets doesn't affect the advanced scale + await addSetByName(page, 'Blue Hair'); + await expect(page.getByText('15').nth(3)).toBeVisible(); + + // Ensure that scale recalculates correctly when advanced is turned off + await toggleAdvancedScale(page); + await expect(page.locator('g').filter({ hasText: /^33$/ }).locator('text').nth(1)).toBeVisible(); +}); \ No newline at end of file From 024a6d6673225a89e3f6af3b0f972e57ed0cfb86 Mon Sep 17 00:00:00 2001 From: Nate Lanza Date: Thu, 4 Apr 2024 13:46:05 -0600 Subject: [PATCH 4/5] Fix webkit issues with playwright tests --- e2e-tests/plot.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/e2e-tests/plot.spec.ts b/e2e-tests/plot.spec.ts index 6db387ae..e6066fe5 100644 --- a/e2e-tests/plot.spec.ts +++ b/e2e-tests/plot.spec.ts @@ -36,7 +36,8 @@ test.beforeEach(async ({ page }) => { */ async function toggleAdvancedScale(page) { await page.getByText('Size', { exact: true }).click({ - button: 'right' + button: 'right', + force: true, }); await page.getByRole('menuitem', { name: 'Toggle Advanced Scale' }).click(); } @@ -85,7 +86,7 @@ test('Size header', async ({ page }) => { // Ensure that dragging the advanced slider works await toggleAdvancedScale(page); await page.locator('g').filter({ hasText: /^0055101015152020Size001122334455$/ }).locator('rect').nth(1). - dragTo(page.getByText('15', { exact: true }).nth(1)); + dragTo(page.getByText('15', { exact: true }).nth(1), {force: true}); await expect(page.getByText('15').nth(3)).toBeVisible(); // Ensure that adding sets doesn't affect the advanced scale From 55aa8891c87bafd9b3b1fa173e6550ea8ddcce6a Mon Sep 17 00:00:00 2001 From: Nate Lanza Date: Fri, 5 Apr 2024 13:54:38 -0600 Subject: [PATCH 5/5] Make test more robust & abstract asserting size scale max --- e2e-tests/plot.spec.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/e2e-tests/plot.spec.ts b/e2e-tests/plot.spec.ts index e6066fe5..882ba107 100644 --- a/e2e-tests/plot.spec.ts +++ b/e2e-tests/plot.spec.ts @@ -64,6 +64,16 @@ async function addSetByName(page, setName: string) { await page.getByRole('menuitem', { name: 'Add Set: ' + setName }).click(); } +/** + * Asserts that the max value of the size scale is equal to the given max value + * @param page page provided to test + * @param max max value to assert + */ +async function assertSizeScaleMax(page, max: number) { + await expect(page.locator('g.details-scale > g > g:last-child > text').nth(1)) + .toHaveText(new RegExp('^' + max + '$')); +} + /** * Tests that the size header resizes when sets are added/removed and the advanced scale slider works */ @@ -71,29 +81,29 @@ test('Size header', async ({ page }) => { await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193'); // Ensure that the scale increases when necessary upon set removal - await expect(page.locator('g').filter({ hasText: /^33$/ }).locator('text').nth(1)).toBeVisible(); + await assertSizeScaleMax(page, 3); await removeSetByName(page, 'Blue Hair'); - await expect(page.getByText('5', { exact: true }).nth(1)).toBeVisible(); + await assertSizeScaleMax(page, 5); // Ensure that the scale decreases when necessary upon set removal await removeSetByName(page, 'Male'); - await expect(page.getByText('8', { exact: true }).nth(1)).toBeVisible(); + await assertSizeScaleMax(page, 8); // Ensure that the scale updates upon set addition await addSetByName(page, 'Male'); - await expect(page.getByText('5', { exact: true }).nth(1)).toBeVisible(); + await assertSizeScaleMax(page, 5); // Ensure that dragging the advanced slider works await toggleAdvancedScale(page); await page.locator('g').filter({ hasText: /^0055101015152020Size001122334455$/ }).locator('rect').nth(1). dragTo(page.getByText('15', { exact: true }).nth(1), {force: true}); - await expect(page.getByText('15').nth(3)).toBeVisible(); + await assertSizeScaleMax(page, 15); // Ensure that adding sets doesn't affect the advanced scale await addSetByName(page, 'Blue Hair'); - await expect(page.getByText('15').nth(3)).toBeVisible(); + await assertSizeScaleMax(page, 15); // Ensure that scale recalculates correctly when advanced is turned off await toggleAdvancedScale(page); - await expect(page.locator('g').filter({ hasText: /^33$/ }).locator('text').nth(1)).toBeVisible(); + await assertSizeScaleMax(page, 3); }); \ No newline at end of file