Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ You can also check the
- Added color palettes to bar chart type
- Maintenance
- Added authentication method to e2e tests
- Added e2e tests for custom color palettes
- Added authentication to Vercel previews for easier testing

# [5.2.4] - 2025-02-06
Expand Down
2 changes: 1 addition & 1 deletion app/charts/shared/legend-color.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export const LegendColor = memo(function LegendColor({
variant="caption"
color="primary.main"
>
{segmentComponent.label}
{segmentComponent?.label}
</Typography>
</OpenMetadataPanelWrapper>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ const CategoricalColorPaletteCreator = (props: ColorPaletteCreatorProps) => {
<Button
variant="text"
fullWidth
data-testid="profile-add-new-color"
className={classes.addColorButton}
disabled={disabled}
startIcon={<Icon name="add" />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const ProfileColorPaletteContent = ({ title }: ProfileContentProps) => {
startIcon={<Icon name="add" />}
sx={{ width: "fit-content" }}
onClick={showAddForm}
data-testid="add-profile-color-palette"
>
<Trans id="login.profile.my-color-palettes.add" />
</Button>
Expand Down Expand Up @@ -153,6 +154,7 @@ const ColorPaletteRow = ({

return (
<ColorRowFlex
data-testid="profile-color-palette-row"
sx={{
paddingY: 3,
paddingRight: 4,
Expand All @@ -161,7 +163,9 @@ const ColorPaletteRow = ({
}}
>
<Box>
<Typography variant="caption">{name}</Typography>
<Typography data-testid="custom-color-palette-title" variant="caption">
{name}
</Typography>
<Grid
container
spacing={0.5}
Expand All @@ -184,20 +188,21 @@ const ColorPaletteRow = ({
</Box>
<ColorRowFlex gap={3}>
<EditButton onClick={() => onEdit(paletteId)}>
<VisuallyHidden>
<Trans id="login.profile.my-color-palettes.edit">
Edit Color Palette
</Trans>
</VisuallyHidden>
<Typography
aria-hidden
color="primary"
sx={{ backgroundColor: "transparent" }}
>
<VisuallyHidden>
<Trans id="login.profile.my-color-palettes.edit">
Edit Color Palette
</Trans>
</VisuallyHidden>
<Icon name="edit" size={24} />
</Typography>
</EditButton>
<DeleteButton
data-testid="profile-delete-color-palette"
disabled={deleteColorPalette.status === "fetching"}
onClick={handleDelete}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ const ProfileColorPaletteForm = ({
<Box className={classes.saveButtonContainer}>
<Button
onClick={saveColorPalette}
data-testid="profile-save-color-palette"
disabled={
colorValues.length === 0 || titleInput === "" || noChanges
}
Expand Down Expand Up @@ -306,12 +307,14 @@ const ColorPaletteTypeSelector = ({
flexDirection={"column"}
gap={2}
>
<Radio
label={colorTypes[type]}
value={type}
checked={type === selectedType}
onChange={handleChange}
/>
<Box data-testid={`profile-color-palette-${type}`}>
<Radio
label={colorTypes[type]}
value={type}
checked={type === selectedType}
onChange={handleChange}
/>
</Box>
<ColorPaletteExample type={type} />
</Flex>
);
Expand Down
3 changes: 2 additions & 1 deletion app/login/components/login-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ export const LoginMenu = () => {
size="small"
onClick={() =>
isVercelPreviewHost(window.location.host) ||
process.env.E2E_ENV === "true"
process.env.E2E_ENV === "true" ||
process.env.NODE_ENV === "development"
? signIn("credentials")
: signIn("adfs")
}
Expand Down
234 changes: 234 additions & 0 deletions e2e/custom-color-palette.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
import { Page } from "@playwright/test";

import { setup, sleep } from "./common";

const { test, expect } = setup();

const clearColorPalettes = async (page: Page) => {
while (true) {
const deleteButtonCount = await page
.locator('[data-testid="profile-delete-color-palette"]')
.count();

if (deleteButtonCount === 0) {
break;
}

await page
.locator('[data-testid="profile-delete-color-palette"]')
.first()
.click();

await page.waitForTimeout(500);
}
};

const addNewColor = async (page: Page, i: number) => {
await page.locator('[data-testid="profile-add-new-color"]').click();

await page.getByRole("button", { name: "Open Color Picker" }).last().click();
await sleep(1_000);

const saturation = page.locator('[data-testid="color-picker-saturation"]');
await saturation.waitFor({ state: "visible", timeout: 5000 });

const box = await saturation.boundingBox();
if (!box) {
throw new Error("Could not get saturation element bounding box");
}

const randomX = box.x + Math.random() * box.width;
const randomY = box.y + Math.random() * box.height;

await page.mouse.click(randomX, randomY);
await sleep(1_000);
await page.keyboard.press("Escape");
};

test("Custom color palettes on profile page should allow CREATE, UPDATE and DELETING palettes ", async ({
page,
auth,
}) => {
test.slow();

await page.goto("/en");
await auth();
await page.waitForLoadState("networkidle");
await page.goto("/en/profile");
const url = page.url();
expect(url.endsWith("/en/profile")).toBe(true);
const tab = page.locator('[data-testid="color-palettes-tab"]');
await tab.waitFor({ state: "visible", timeout: 5000 });
await tab.click();

await page.waitForLoadState("networkidle");
await clearColorPalettes(page);

//Create Categorical Palette
await page.locator('[data-testid="add-profile-color-palette"]').click();
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await sleep(1_000);

const categoricalTitleInput = page.locator(
'input[name="custom-color-palette-title"]'
);
await categoricalTitleInput.waitFor({ state: "visible", timeout: 5000 });
await categoricalTitleInput.click();
await categoricalTitleInput.fill("Categorical Palette");
await page.keyboard.press("Enter");
await page.waitForTimeout(500);

for (let i = 0; i < 3; i++) {
await addNewColor(page, i);
}
await page.locator('[data-testid="profile-save-color-palette"]').click();
await page.waitForLoadState("networkidle");
await sleep(1_000);

const categoricalTitleExists = await page
.getByText("Categorical Palette")
.isVisible();
expect(categoricalTitleExists).toBe(true);

//Create Sequential Palette
await page.locator('[data-testid="add-profile-color-palette"]').click();
await page
.locator('[data-testid="profile-color-palette-sequential"]')
.click();
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await page.waitForLoadState("networkidle");
await sleep(1_000);

const sequentialTitleInput = page.locator(
'input[name="custom-color-palette-title"]'
);
await sequentialTitleInput.waitFor({ state: "visible", timeout: 5000 });
await sequentialTitleInput.click();
await sequentialTitleInput.fill("Sequential Palette");
await page.keyboard.press("Enter");
await page.waitForTimeout(500);

await page.locator('[data-testid="profile-save-color-palette"]').click();
await sleep(1_000);

const sequentialTitleExists = await page
.getByText("Sequential Palette")
.isVisible();
expect(sequentialTitleExists).toBe(true);

//Create Diverging Palette (2 colors)
await page.locator('[data-testid="add-profile-color-palette"]').click();
await page.locator('[data-testid="profile-color-palette-diverging"]').click();
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await sleep(1_000);

const divergingTwoTitleInput = page.locator(
'input[name="custom-color-palette-title"]'
);
await divergingTwoTitleInput.waitFor({ state: "visible", timeout: 5000 });
await divergingTwoTitleInput.click();
await divergingTwoTitleInput.fill("Diverging Palette (2)");
await page.keyboard.press("Enter");
await page.waitForTimeout(500);

await page.getByRole("button", { name: "Remove Color" }).first().click();
await sleep(1_000);

await page.locator('[data-testid="profile-save-color-palette"]').click();
await page.waitForLoadState("networkidle");
await sleep(1_000);

const divergingTwoTitleExists = await page
.getByText("Diverging Palette (2)")
.isVisible();
expect(divergingTwoTitleExists).toBe(true);

//Create Diverging Palette (3 colors)
await page.locator('[data-testid="add-profile-color-palette"]').click();
await page.locator('[data-testid="profile-color-palette-diverging"]').click();
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await sleep(1_000);

const divergingThreeTitleInput = page.locator(
'input[name="custom-color-palette-title"]'
);
await divergingThreeTitleInput.waitFor({ state: "visible", timeout: 5000 });
await divergingThreeTitleInput.click();
await divergingThreeTitleInput.fill("Diverging Palette (3)");
await page.keyboard.press("Enter");
await page.waitForTimeout(500);

await page.locator('[data-testid="profile-save-color-palette"]').click();
await page.waitForLoadState("networkidle");
await sleep(1_000);

const divergingThreeTitleExists = await page
.getByText("Diverging Palette (3)")
.isVisible();
expect(divergingThreeTitleExists).toBe(true);

//Update Color palettes
//Edit Categorical Palette add more colors
await page
.getByRole("button", { name: "login.profile.my-color-palettes.edit" })
.first()
.click();

await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await sleep(1_000);

for (let i = 0; i < 3; i++) {
await addNewColor(page, i);
}
await page.locator('[data-testid="profile-save-color-palette"]').click();
await sleep(1_000);

//Edit Sequential Palette change type
await page
.getByRole("button", { name: "login.profile.my-color-palettes.edit" })
.first()
.click();
await page
.locator('[data-testid="profile-color-palette-categorical"]')
.click();

await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await sleep(1_000);

for (let i = 0; i < 3; i++) {
await addNewColor(page, i);
}
await page.locator('[data-testid="profile-save-color-palette"]').click();
await sleep(1_000);

//Delete Color palettes
const paletteNames = [
"Categorical Palette",
"Sequential Palette",
"Diverging Palette (2)",
"Diverging Palette (3)",
];

for (const paletteName of paletteNames) {
const allRows = page.locator('[data-testid="profile-color-palette-row"]');
const count = await allRows.count();

for (let i = 0; i < count; i++) {
const row = allRows.nth(i);

const titleElement = row.locator(
'[data-testid="custom-color-palette-title"]'
);
const titleText = await titleElement.textContent();

if (titleText && titleText.trim() === paletteName.trim()) {
await row
.locator('[data-testid="profile-delete-color-palette"]')
.click();

await page.waitForTimeout(300);
break;
}
}
}
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
"postversion": "git push --follow-tags",
"release:npm": "yarn build:npm && yarn publish app",
"e2e:dev": "E2E_BASE_URL=http://localhost:3000 yarn playwright test",
"e2e:dev:ssl": "E2E_BASE_URL=https://localhost:3000 yarn playwright test",
"e2e:dev:ssl": "E2E_BASE_URL=https://localhost:3000 E2E_ENV=true yarn playwright test",
"e2e:ui": "E2E_BASE_URL=http://localhost:3000 yarn playwright test --ui",
"e2e:ui:ssl": "E2E_BASE_URL=https://localhost:3000 yarn playwright test --ui",
"e2e:ui:ssl": "E2E_BASE_URL=https://localhost:3000 E2E_ENV=true yarn playwright test --ui",
"e2e": "playwright test",
"cube": "NODE_ENV=development ts-node app/scripts/cube.ts",
"dev:circular-deps": "madge --warning --extensions js,jsx,ts,tsx -b ./app -c ./app/pages/ --ts-config ./app/tsconfig.json | bun scripts/circular-deps-analysis.ts -",
Expand Down
Loading