mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-04 07:18:11 +08:00
1510-smoke-test (#1548)
* 1510-smoke-test * config default * update tests * update test config * fix linter errors * more comments * address comments * use npm install in push_tests.yml * use environment.default.json * adding docs * Take care of @mweiden's nits * Save screenshots in the __tests__/screenshots/ directory * typo * docs * Add chart tests (#1580) * merge tests * check if bin creation returned null before rendering charts (#1576) * check if bin creation returned null before rendering charts * refactor chart rendering into functions (#1577) * little fixes from PR * reintroduce fix to check for null values * change getAllByClass to return element * slice instead * new stackedbar test * feedback-1573-test (#1579) * feedback-1573-test * enable whole test set * revert tests Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com> * tweak test to actually render chart * include snapshot * remove async * fix getAllHistograms * properly grab id Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com> Co-authored-by: Matt Weiden <538456+mweiden@users.noreply.github.com> Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com>
This commit is contained in:
co-authored by
Matt Weiden
Severiano Badajoz
parent
e22e671f10
commit
83376627e8
@@ -1,208 +1,304 @@
|
||||
/*
|
||||
Tests included in this file are specific to annotation features
|
||||
*/
|
||||
import { appUrlBase, DATASET, DEBUG } from "./config";
|
||||
import setupTestBrowser from "./testBrowser";
|
||||
import { appUrlBase, DATASET } from "./config";
|
||||
import { datasets } from "./data";
|
||||
|
||||
let browser;
|
||||
let page;
|
||||
let utils;
|
||||
let actions;
|
||||
import {
|
||||
clickOn,
|
||||
goToPage,
|
||||
waitByClass,
|
||||
waitByID,
|
||||
getTestId,
|
||||
getTestClass,
|
||||
getAllByClass,
|
||||
} from "./puppeteerUtils";
|
||||
|
||||
import {
|
||||
assertCategoryDoesNotExist,
|
||||
calcDragCoordinates,
|
||||
createCategory,
|
||||
createLabel,
|
||||
deleteCategory,
|
||||
deleteLabel,
|
||||
drag,
|
||||
expandCategory,
|
||||
renameCategory,
|
||||
renameLabel,
|
||||
subset,
|
||||
duplicateCategory,
|
||||
} from "./cellxgeneActions";
|
||||
|
||||
const data = datasets[DATASET];
|
||||
|
||||
beforeAll(async () => {
|
||||
[browser, page, utils, actions] = await setupTestBrowser();
|
||||
});
|
||||
const perTestCategoryName = "TEST-CATEGORY";
|
||||
const perTestLabelName = "TEST-LABEL";
|
||||
|
||||
afterAll(async () => {
|
||||
if (!DEBUG && browser !== undefined) await browser.close();
|
||||
});
|
||||
async function setup(config) {
|
||||
await goToPage(appUrlBase);
|
||||
|
||||
// setup the test fixtures
|
||||
await createCategory(perTestCategoryName);
|
||||
await createLabel(perTestCategoryName, perTestLabelName);
|
||||
|
||||
if (config.withSubset) {
|
||||
await subset({ x1: 0.1, y1: 0.1, x2: 0.8, y2: 0.8 });
|
||||
}
|
||||
|
||||
await waitByClass("autosave-complete");
|
||||
}
|
||||
|
||||
describe.each([
|
||||
{ withSubset: true, tag: "subset" },
|
||||
{ withSubset: false, tag: "whole" },
|
||||
])("annotations", (config) => {
|
||||
const perTestCategoryName = "per-test-category";
|
||||
const perTestLabelName = "per-test-label";
|
||||
|
||||
beforeEach(async () => {
|
||||
await page.goto(appUrlBase);
|
||||
|
||||
// wait for the page to load
|
||||
await utils.waitByClass("autosave-complete");
|
||||
// setup the test fixtures
|
||||
await actions.createCategory(perTestCategoryName);
|
||||
await actions.createLabel(perTestCategoryName, perTestLabelName);
|
||||
if (config.withSubset)
|
||||
await actions.subset({ x1: 0.1, y1: 0.1, x2: 0.8, y2: 0.8 });
|
||||
await utils.waitByClass("autosave-complete");
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteCategoryIfExists(perTestCategoryName);
|
||||
await utils.waitByClass("autosave-complete");
|
||||
});
|
||||
|
||||
test("create a category", async () => {
|
||||
await setup(config);
|
||||
|
||||
const categoryName = `category-created-${config.tag}`;
|
||||
|
||||
await assertCategoryDoesNotExist(categoryName);
|
||||
await actions.createCategory(categoryName);
|
||||
|
||||
await createCategory(categoryName);
|
||||
|
||||
await assertCategoryExists(categoryName);
|
||||
});
|
||||
|
||||
test("delete a category", async () => {
|
||||
await actions.deleteCategory(perTestCategoryName);
|
||||
await setup(config);
|
||||
|
||||
await deleteCategory(perTestCategoryName);
|
||||
await assertCategoryDoesNotExist(perTestCategoryName);
|
||||
});
|
||||
|
||||
test("rename a category", async () => {
|
||||
const newCategoryName = `cluster-for-real-${config.tag}`;
|
||||
await actions.renameCategory(perTestCategoryName, newCategoryName);
|
||||
await setup(config);
|
||||
|
||||
const newCategoryName = `NEW-${config.tag}`;
|
||||
|
||||
await renameCategory(perTestCategoryName, newCategoryName);
|
||||
await assertCategoryDoesNotExist(perTestCategoryName);
|
||||
await assertCategoryExists(newCategoryName);
|
||||
});
|
||||
|
||||
test("create a label", async () => {
|
||||
await setup(config);
|
||||
|
||||
const labelName = `new-label-${config.tag}`;
|
||||
|
||||
await assertLabelDoesNotExist(perTestCategoryName, labelName);
|
||||
await actions.createLabel(perTestCategoryName, labelName);
|
||||
|
||||
await createLabel(perTestCategoryName, labelName);
|
||||
|
||||
await assertLabelExists(perTestCategoryName, labelName);
|
||||
});
|
||||
|
||||
test("delete a label", async () => {
|
||||
await actions.deleteLabel(perTestCategoryName, perTestLabelName);
|
||||
await setup(config);
|
||||
|
||||
await deleteLabel(perTestCategoryName, perTestLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
|
||||
});
|
||||
|
||||
test("rename a label", async () => {
|
||||
await setup(config);
|
||||
|
||||
const newLabelName = "my-cool-new-label";
|
||||
|
||||
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
|
||||
await actions.renameLabel(
|
||||
perTestCategoryName,
|
||||
perTestLabelName,
|
||||
newLabelName
|
||||
);
|
||||
await renameLabel(perTestCategoryName, perTestLabelName, newLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
|
||||
await assertLabelExists(perTestCategoryName, newLabelName);
|
||||
});
|
||||
|
||||
test("check cell count for a label loaded from file", async () => {
|
||||
const categoryName = "cluster-test";
|
||||
const labelName = "four";
|
||||
await actions.expandCategory(categoryName);
|
||||
const result = await utils.waitByID(
|
||||
`categorical-value-count-${categoryName}-${labelName}`
|
||||
await setup(config);
|
||||
|
||||
const duplicateCategoryName = "duplicate";
|
||||
await duplicateCategory(duplicateCategoryName);
|
||||
|
||||
await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] });
|
||||
|
||||
const firstCategoryExpandIcon = await expect(page).toMatchElement(
|
||||
getTestClass("category-expand")
|
||||
);
|
||||
expect(await result.evaluate((node) => node.innerText)).toBe(
|
||||
data.annotationsFromFile.count.bySubsetConfig[config.withSubset]
|
||||
|
||||
await firstCategoryExpandIcon.click();
|
||||
|
||||
const expectedCategoryRow = await expect(page).toMatchElement(
|
||||
getTestClass("categorical-row")
|
||||
);
|
||||
const expectedLabelName = await getInnerText(
|
||||
expectedCategoryRow,
|
||||
"categorical-value"
|
||||
);
|
||||
const expectedLabelCount = await getInnerText(
|
||||
expectedCategoryRow,
|
||||
"categorical-value-count"
|
||||
);
|
||||
|
||||
await expandCategory(duplicateCategoryName);
|
||||
|
||||
const expectedCategory = await expect(page).toMatchElement(
|
||||
getTestClass("category")
|
||||
);
|
||||
|
||||
const actualCategoryRow = await expect(expectedCategory).toMatchElement(
|
||||
getTestClass("categorical-row")
|
||||
);
|
||||
const actualLabelName = await getInnerText(
|
||||
actualCategoryRow,
|
||||
"categorical-value"
|
||||
);
|
||||
const actualLabelCount = await getInnerText(
|
||||
actualCategoryRow,
|
||||
"categorical-value-count"
|
||||
);
|
||||
|
||||
expect(actualLabelName).toBe(expectedLabelName);
|
||||
expect(actualLabelCount).toBe(expectedLabelCount);
|
||||
|
||||
async function getInnerText(element, className) {
|
||||
return element.$eval(getTestClass(className), (node) => node?.innerText);
|
||||
}
|
||||
});
|
||||
|
||||
test("assign cells to a label", async () => {
|
||||
await actions.expandCategory(perTestCategoryName);
|
||||
const lassoSelection = await actions.calcDragCoordinates(
|
||||
await setup(config);
|
||||
|
||||
await expandCategory(perTestCategoryName);
|
||||
|
||||
const lassoSelection = await calcDragCoordinates(
|
||||
"layout-graph",
|
||||
data.categoryLabel.lasso["coordinates-as-percent"]
|
||||
);
|
||||
await actions.drag(
|
||||
"layout-graph",
|
||||
lassoSelection.start,
|
||||
lassoSelection.end,
|
||||
true
|
||||
);
|
||||
await utils.waitByID("lasso-element", { visible: true });
|
||||
await utils.clickOn(
|
||||
`${perTestCategoryName}:${perTestLabelName}:see-actions`
|
||||
);
|
||||
await utils.clickOn(
|
||||
|
||||
await drag("layout-graph", lassoSelection.start, lassoSelection.end, true);
|
||||
await waitByID("lasso-element", { visible: true });
|
||||
await clickOn(`${perTestCategoryName}:${perTestLabelName}:see-actions`);
|
||||
await clickOn(
|
||||
`${perTestCategoryName}:${perTestLabelName}:add-current-selection-to-this-label`
|
||||
);
|
||||
const result = await utils.waitByID(
|
||||
|
||||
const result = await waitByID(
|
||||
`categorical-value-count-${perTestCategoryName}-${perTestLabelName}`
|
||||
);
|
||||
|
||||
expect(await result.evaluate((node) => node.innerText)).toBe(
|
||||
data.categoryLabel.newCount.bySubsetConfig[config.withSubset]
|
||||
);
|
||||
});
|
||||
|
||||
test("undo/redo category creation", async () => {
|
||||
await setup(config);
|
||||
|
||||
const categoryName = `category-created-undo-${config.tag}`;
|
||||
|
||||
await assertCategoryDoesNotExist(categoryName);
|
||||
await actions.createCategory(categoryName);
|
||||
await createCategory(categoryName);
|
||||
await assertCategoryExists(categoryName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertCategoryDoesNotExist(categoryName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertCategoryExists(categoryName);
|
||||
});
|
||||
|
||||
test("undo/redo category deletion", async () => {
|
||||
await setup(config);
|
||||
|
||||
const categoryName = `category-deleted-undo-${config.tag}`;
|
||||
await actions.createCategory(categoryName);
|
||||
|
||||
await createCategory(categoryName);
|
||||
await assertCategoryExists(categoryName);
|
||||
await actions.deleteCategory(categoryName);
|
||||
await deleteCategory(categoryName);
|
||||
await assertCategoryDoesNotExist(categoryName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertCategoryExists(categoryName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertCategoryDoesNotExist(categoryName);
|
||||
});
|
||||
|
||||
test("undo/redo category rename", async () => {
|
||||
await setup(config);
|
||||
|
||||
const newCategoryName = `category-renamed-undo-${config.tag}`;
|
||||
|
||||
await assertCategoryDoesNotExist(newCategoryName);
|
||||
await actions.renameCategory(perTestCategoryName, newCategoryName);
|
||||
await renameCategory(perTestCategoryName, newCategoryName);
|
||||
await assertCategoryExists(newCategoryName);
|
||||
await assertCategoryDoesNotExist(perTestCategoryName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertCategoryExists(perTestCategoryName);
|
||||
await assertCategoryDoesNotExist(newCategoryName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertCategoryExists(newCategoryName);
|
||||
await assertCategoryDoesNotExist(perTestCategoryName);
|
||||
});
|
||||
|
||||
test("undo/redo label creation", async () => {
|
||||
await setup(config);
|
||||
|
||||
const labelName = `label-created-undo-${config.tag}`;
|
||||
|
||||
await assertLabelDoesNotExist(perTestCategoryName, labelName);
|
||||
await actions.createLabel(perTestCategoryName, labelName);
|
||||
await createLabel(perTestCategoryName, labelName);
|
||||
await assertLabelExists(perTestCategoryName, labelName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertLabelDoesNotExist(perTestCategoryName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertLabelExists(perTestCategoryName, labelName);
|
||||
});
|
||||
|
||||
test("undo/redo label deletion", async () => {
|
||||
await actions.deleteLabel(perTestCategoryName, perTestLabelName);
|
||||
await setup(config);
|
||||
|
||||
await deleteLabel(perTestCategoryName, perTestLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertLabelExists(perTestCategoryName, perTestLabelName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertLabelDoesNotExist(perTestCategoryName);
|
||||
});
|
||||
|
||||
test("undo/redo label rename", async () => {
|
||||
await setup(config);
|
||||
|
||||
const newLabelName = `label-renamed-undo-${config.tag}`;
|
||||
|
||||
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
|
||||
await actions.renameLabel(
|
||||
perTestCategoryName,
|
||||
perTestLabelName,
|
||||
newLabelName
|
||||
);
|
||||
await renameLabel(perTestCategoryName, perTestLabelName, newLabelName);
|
||||
await assertLabelExists(perTestCategoryName, newLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
|
||||
await utils.clickOn("undo");
|
||||
await clickOn("undo");
|
||||
await assertLabelExists(perTestCategoryName, perTestLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
|
||||
await utils.clickOn("redo");
|
||||
await clickOn("redo");
|
||||
await assertLabelExists(perTestCategoryName, newLabelName);
|
||||
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
|
||||
});
|
||||
|
||||
test("stacked bar graph renders", async () => {
|
||||
await setup(config);
|
||||
|
||||
await expandCategory(perTestCategoryName);
|
||||
|
||||
await clickOn(`colorby-louvain`);
|
||||
|
||||
const labels = await getAllByClass("categorical-row");
|
||||
|
||||
const result = await Promise.all(
|
||||
labels.map((label) => {
|
||||
return page.evaluate((element) => {
|
||||
return element.outerHTML;
|
||||
}, label);
|
||||
})
|
||||
);
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
|
||||
async function assertCategoryExists(categoryName) {
|
||||
const handle = await utils.waitByID(`${categoryName}:category-label`);
|
||||
const handle = await waitByID(`${categoryName}:category-label`);
|
||||
|
||||
const result = await handle.evaluate((node) =>
|
||||
node.getAttribute("aria-label")
|
||||
@@ -211,37 +307,27 @@ describe.each([
|
||||
expect(result).toBe(categoryName);
|
||||
}
|
||||
|
||||
async function assertCategoryDoesNotExist(categoryName) {
|
||||
const result = await page.$(
|
||||
`[data-testid='${categoryName}:category-label']`
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
}
|
||||
|
||||
async function assertLabelExists(categoryName, labelName) {
|
||||
const category = await utils.waitByID(`${categoryName}:category-expand`);
|
||||
expect(category).not.toBeNull();
|
||||
await actions.expandCategory(categoryName);
|
||||
const previous = await utils.waitByID(
|
||||
await expect(page).toMatchElement(
|
||||
getTestId(`${categoryName}:category-expand`)
|
||||
);
|
||||
|
||||
await expandCategory(categoryName);
|
||||
|
||||
const previous = await waitByID(
|
||||
`categorical-value-${categoryName}-${labelName}`
|
||||
);
|
||||
|
||||
expect(
|
||||
await previous.evaluate((node) => node.getAttribute("aria-label"))
|
||||
).toBe(labelName);
|
||||
}
|
||||
|
||||
async function assertLabelDoesNotExist(categoryName, labelName) {
|
||||
await actions.expandCategory(categoryName);
|
||||
await expandCategory(categoryName);
|
||||
const result = await page.$(
|
||||
`[data-testid='categorical-value-${categoryName}-${labelName}']`
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
}
|
||||
|
||||
async function deleteCategoryIfExists(categoryName) {
|
||||
const handle = await page.$(
|
||||
`[data-testid='${categoryName}:category-expand']`
|
||||
);
|
||||
if (handle) await actions.deleteCategory(categoryName);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user