genesets e2e tests (#2241)

* __test: create geneset

* example dataset test geneset

* delete geneset test

* edit __test

* gene crud

* Update client/Makefile

Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com>

* copy gene sets separately

* make fix

* ignore test files locally

* csv update

* updated csvs

* fix unit tests for gene set load routes

* add missing fix to czi_hosted unit test

* pin tiledb version, for czi_hosted backend, to <0.9

* Revert tiledb pin to be less than 0.9. Broken tests have been updated in main branch.

* newline, gitignore

* color by and subset

* diffexp sets equal

* add diff exp test class

* fix data class

* diffexp snapshot

* snapshot

* snap3

* snapshot parentInnerhtml

* remove snap

* updated anno snaps

* add test class to gene list div

* new snapshots

* kick off

* Revert "kick off"

This reverts commit 743f551d55.

* remove import

* eol

* revert changes to csv re: gene tests

* global name

Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com>
Co-authored-by: bkmartinjr <bruce@chanzuckerberg.com>
Co-authored-by: Arathi Mani <arathi.mani@chanzuckerberg.com>
Co-authored-by: maniarathi <mani.arathi@gmail.com>
This commit is contained in:
Colin Megill
2021-07-01 18:29:06 -07:00
committed by GitHub
parent b714c18e75
commit face1b3033
21 changed files with 564 additions and 47 deletions

View File

@@ -5,8 +5,8 @@ first gene set name,a description,NO_SUCH_GENE, non-existent gene
first gene set name,a description,F5, duplicate gene
first gene set name, a description,SUMO3,
first gene set name,,SRM,
second gene set,,RER1
second gene set,,SIK1
second_gene_set,,RER1
second_gene_set,,SIK1
third gene set,,NO_SUCH_GENE
fourth_gene_set,fourth description,,gene intentionally missing
fifth_dataset,,,
@@ -14,3 +14,8 @@ summary test,,ACD,
summary test,,AATF,
summary test,,F5,
summary test,,PIGU,
geneset_to_delete,,,
geneset_to_edit,,,
fill_this_geneset,,RER1,
empty_this_geneset,,SIK1,
brush_this_gene,,SIK1,
1 # Test fixture
5 first gene set name,a description,F5, duplicate gene
6 first gene set name, a description,SUMO3,
7 first gene set name,,SRM,
8 second gene set,,RER1 second_gene_set,,RER1
9 second gene set,,SIK1 second_gene_set,,SIK1
10 third gene set,,NO_SUCH_GENE
11 fourth_gene_set,fourth description,,gene intentionally missing
12 fifth_dataset,,,
14 summary test,,AATF,
15 summary test,,F5,
16 summary test,,PIGU,
17 geneset_to_delete,,,
18 geneset_to_edit,,,
19 fill_this_geneset,,RER1,
20 empty_this_geneset,,SIK1,
21 brush_this_gene,,SIK1,

View File

@@ -453,7 +453,7 @@ class EndPointsCxg(EndPoints):
{"gene_description": "", "gene_symbol": "SIK1"},
],
"geneset_description": "",
"geneset_name": "second gene set",
"geneset_name": "second_gene_set",
},
{"genes": [], "geneset_description": "", "geneset_name": "third gene set"},
{"genes": [], "geneset_description": "fourth description", "geneset_name": "fourth_gene_set"},
@@ -468,6 +468,23 @@ class EndPointsCxg(EndPoints):
"geneset_description": "",
"geneset_name": "summary test",
},
{'genes': [], 'geneset_description': '', 'geneset_name': 'geneset_to_delete'},
{'genes': [], 'geneset_description': '', 'geneset_name': 'geneset_to_edit'},
{
'genes': [{'gene_description': '', 'gene_symbol': 'RER1'}],
'geneset_description': '',
'geneset_name': 'fill_this_geneset'
},
{
'genes': [{'gene_description': '', 'gene_symbol': 'SIK1'}],
'geneset_description': '',
'geneset_name': 'empty_this_geneset'
},
{
'genes': [{'gene_description': '', 'gene_symbol': 'SIK1'}],
'geneset_description': '',
'geneset_name': 'brush_this_gene'
}
],
"tid": 0,
},
@@ -484,8 +501,8 @@ class EndPointsCxg(EndPoints):
first gene set name,a description,F5, a gene_description\r
first gene set name,a description,SUMO3,\r
first gene set name,a description,SRM,\r
second gene set,,RER1,\r
second gene set,,SIK1,\r
second_gene_set,,RER1,\r
second_gene_set,,SIK1,\r
third gene set,,,\r
fourth_gene_set,fourth description,,\r
fifth_dataset,,,\r
@@ -493,6 +510,11 @@ summary test,,ACD,\r
summary test,,AATF,\r
summary test,,F5,\r
summary test,,PIGU,\r
geneset_to_delete,,,\r
geneset_to_edit,,,\r
fill_this_geneset,,RER1,\r
empty_this_geneset,,SIK1,\r
brush_this_gene,,SIK1,\r
"""
self.assertEqual(result.data.decode("utf-8"), expected_data)

View File

@@ -575,7 +575,7 @@ class EndPointsAnnDataGenesets(unittest.TestCase, EndPoints):
{"gene_description": "", "gene_symbol": "SIK1"},
],
"geneset_description": "",
"geneset_name": "second gene set",
"geneset_name": "second_gene_set",
},
{"genes": [], "geneset_description": "", "geneset_name": "third gene set"},
{"genes": [], "geneset_description": "fourth description", "geneset_name": "fourth_gene_set"},
@@ -590,6 +590,23 @@ class EndPointsAnnDataGenesets(unittest.TestCase, EndPoints):
"geneset_description": "",
"geneset_name": "summary test",
},
{'genes': [], 'geneset_description': '', 'geneset_name': 'geneset_to_delete'},
{'genes': [], 'geneset_description': '', 'geneset_name': 'geneset_to_edit'},
{
'genes': [{'gene_description': '', 'gene_symbol': 'RER1'}],
'geneset_description': '',
'geneset_name': 'fill_this_geneset'
},
{
'genes': [{'gene_description': '', 'gene_symbol': 'SIK1'}],
'geneset_description': '',
'geneset_name': 'empty_this_geneset'
},
{
'genes': [{'gene_description': '', 'gene_symbol': 'SIK1'}],
'geneset_description': '',
'geneset_name': 'brush_this_gene'
}
],
"tid": 0,
},
@@ -607,8 +624,8 @@ class EndPointsAnnDataGenesets(unittest.TestCase, EndPoints):
first gene set name,a description,F5, a gene_description\r
first gene set name,a description,SUMO3,\r
first gene set name,a description,SRM,\r
second gene set,,RER1,\r
second gene set,,SIK1,\r
second_gene_set,,RER1,\r
second_gene_set,,SIK1,\r
third gene set,,,\r
fourth_gene_set,fourth description,,\r
fifth_dataset,,,\r
@@ -616,6 +633,11 @@ summary test,,ACD,\r
summary test,,AATF,\r
summary test,,F5,\r
summary test,,PIGU,\r
geneset_to_delete,,,\r
geneset_to_edit,,,\r
fill_this_geneset,,RER1,\r
empty_this_geneset,,SIK1,\r
brush_this_gene,,SIK1,\r
""",
)

View File

@@ -1,10 +1,13 @@
include ../common.mk
ANNOTATIONS := $(if $(ANNOTATIONS),$(ANNOTATIONS),../backend/test/fixtures/pbmc3k-annotations.csv)
GENE_SETS := $(if $(GENE_SETS),$(GENE_SETS),../backend/test/fixtures/pbmc3k-genesets.csv)
ANNOTATIONS_FILENAME := $(shell basename $(ANNOTATIONS))
GENE_SETS_FILENAME := $(shell basename $(GENE_SETS))
CXG_CONFIG := $(if $(CXG_CONFIG), $(CXG_CONFIG), ./__tests__/e2e/test_config.yaml)
# Packaging
.PHONY: clean
clean:
@@ -42,8 +45,9 @@ smoke-test:
smoke-test-annotations:
$(eval TMP_DIR := $(shell mktemp -d /tmp/cellxgene_XXXXXX))
cp $(ANNOTATIONS) $(TMP_DIR)/ && \
cp $(GENE_SETS) $(TMP_DIR)/ && \
start_server_and_test \
'CXG_OPTIONS="--annotations-file $(TMP_DIR)/$(ANNOTATIONS_FILENAME)" $(MAKE) start-server' \
'CXG_OPTIONS="--annotations-file $(TMP_DIR)/$(ANNOTATIONS_FILENAME) --gene-sets-file $(TMP_DIR)/$(GENE_SETS_FILENAME)" $(MAKE) start-server' \
$(CXG_SERVER_PORT) \
'CXG_URL_BASE="http://localhost:$(CXG_SERVER_PORT)" npm run e2e-annotations -- --verbose false'
rm -rf $(TMP_DIR)

File diff suppressed because one or more lines are too long

View File

@@ -176,6 +176,137 @@ export async function createCategory(categoryName) {
await clickOn("submit-category");
}
/*
GENESET
*/
export async function colorByGeneset(genesetName) {
await clickOn(`${genesetName}:colorby-entire-geneset`);
}
export async function colorByGene(gene) {
await clickOn(`colorby-${gene}`);
}
export async function assertColorLegendLabel(label) {
const handle = await waitByID("continuous_legend_color_by_label");
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
return expect(result).toBe(label);
}
export async function expandGeneset(genesetName) {
const expand = await waitByID(`${genesetName}:geneset-expand`);
const notExpanded = await expand.$(
"[data-testclass='geneset-expand-is-not-expanded']"
);
if (notExpanded) await clickOn(`${genesetName}:geneset-expand`);
}
export async function createGeneset(genesetName) {
await clickOnUntil("open-create-geneset-dialog", async () => {
await expect(page).toMatchElement(getTestId("create-geneset-input"));
});
await typeInto("create-geneset-input", genesetName);
await clickOn("submit-geneset");
await waitByClass("autosave-complete");
}
export async function editGenesetName(genesetName, editText) {
const editButton = `${genesetName}:edit-genesetName-mode`;
const submitButton = `${genesetName}:submit-geneset`;
await clickOnUntil(`${genesetName}:see-actions`, async () => {
await expect(page).toMatchElement(getTestId(editButton));
});
await clickOn(editButton);
await typeInto("rename-geneset-modal", editText);
await clickOn(submitButton);
}
export async function deleteGeneset(genesetName) {
const targetId = `${genesetName}:delete-geneset`;
await clickOnUntil(`${genesetName}:see-actions`, async () => {
await expect(page).toMatchElement(getTestId(targetId));
});
await clickOn(targetId);
await assertGenesetDoesNotExist(genesetName);
await waitByClass("autosave-complete");
}
export async function assertGenesetDoesNotExist(genesetName) {
const result = await isElementPresent(
getTestId(`${genesetName}:geneset-name`)
);
await expect(result).toBe(false);
}
export async function assertGenesetExists(genesetName) {
const handle = await waitByID(`${genesetName}:geneset-name`);
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
return expect(result).toBe(genesetName);
}
/*
GENE
*/
export async function addGeneToSet(genesetName, geneToAddToSet) {
const submitButton = `${genesetName}:submit-gene`;
await clickOn(`${genesetName}:add-new-gene-to-geneset`);
await typeInto("add-genes", geneToAddToSet);
await clickOn(submitButton);
}
export async function removeGene(geneSymbol) {
const targetId = `delete-from-geneset:${geneSymbol}`;
await clickOn(targetId);
await waitByClass("autosave-complete");
}
export async function assertGeneExistsInGeneset(geneSymbol) {
const handle = await waitByID(`${geneSymbol}:gene-label`);
const result = await handle.evaluate((node) => {
return node.getAttribute("aria-label");
});
return expect(result).toBe(geneSymbol);
}
export async function assertGeneDoesNotExist(geneSymbol) {
const result = await isElementPresent(getTestId(`${geneSymbol}:gene-label`));
await expect(result).toBe(false);
}
export async function expandGene(geneSymbol) {
await clickOn(`maximize-${geneSymbol}`);
}
/*
CATEGORY
*/
export async function duplicateCategory(categoryName) {
await clickOn("open-annotation-dialog");

View File

@@ -0,0 +1,105 @@
export const diffexpPop1Genes = [
"CD79A",
"HLA-DRB1",
"HLA-DQA1",
"HLA-DPB1",
"HLA-DQB1",
"HLA-DPA1",
"MS4A1",
"LTB",
"CD79B",
"CD37",
"HLA-DMA",
"TCL1A",
"LINC00926",
"HLA-DMB",
"HVCN1",
"EAF2",
"FCRLA",
"IRF8",
"PKIG",
"P2RX5",
"HLA-DOB",
"SPIB",
"BLNK",
"SWAP70",
"PNOC",
"CD19",
"SMIM14",
"CD72",
"KIAA0125",
"IGLL5",
"ARHGAP24",
"COTL1",
"C16orf74",
"BTK",
"SNX29P2",
"ADAM28",
"FCGR2B",
"PLD4",
"PPP1R14A",
"MZB1",
"KIAA0040",
"PHACTR1",
"FCRL2",
"RIC3",
"P2RY10",
"SCPEP1",
"DRAM2",
"RP5-887A10.1",
"CD82",
"GPX1",
];
export const diffexpPop2Genes = [
"NKG7",
"GZMB",
"CTSW",
"PRF1",
"GNLY",
"GZMA",
"CST7",
"FGFBP2",
"SRGN",
"CD247",
"FCGR3A",
"TYROBP",
"FCER1G",
"ID2",
"SPON2",
"CCL4",
"CCL5",
"GZMH",
"GIMAP7",
"CLIC3",
"HOPX",
"XCL2",
"LGALS1",
"IGFBP7",
"AKR1C3",
"IL32",
"EFHD2",
"PRSS23",
"TTC38",
"ZAP70",
"S1PR5",
"SAMD3",
"GIMAP4",
"CCL3",
"ABI3",
"XCL1",
"S100A6",
"UBB",
"GPR56",
"PDIA3",
"S100A11",
"APOBEC3G",
"HAVCR2",
"PLEKHF1",
"LITAF",
"ARPC5L",
"PTGDR",
"PRMT2",
"GSTP1",
"FCRL6",
];

View File

@@ -12,6 +12,7 @@ import {
getTestId,
getTestClass,
getAllByClass,
getOneElementInnerHTML,
} from "./puppeteerUtils";
import {
@@ -27,6 +28,21 @@ import {
renameLabel,
subset,
duplicateCategory,
createGeneset,
deleteGeneset,
assertGenesetExists,
assertGenesetDoesNotExist,
getCellSetCount,
expandGeneset,
editGenesetName,
addGeneToSet,
assertGeneExistsInGeneset,
removeGene,
assertGeneDoesNotExist,
expandGene,
colorByGeneset,
assertColorLegendLabel,
colorByGene,
} from "./cellxgeneActions";
const data = datasets[DATASET];
@@ -34,12 +50,40 @@ const data = datasets[DATASET];
const perTestCategoryName = "TEST-CATEGORY";
const perTestLabelName = "TEST-LABEL";
// geneset CRUD
const genesetToDeleteName = "geneset_to_delete";
const preExistingGenesetName = "fifth_dataset";
const meanExpressionBrushGenesetName = "second_gene_set";
const meanExpressionBrushCellsSelected = "557";
const subsetMeanExpressionBrushCellsSelected = "452";
// initial text, the text we type in, the result
const editableGenesetName = "geneset_to_edit";
const editText = "_111";
const newGenesetName = "geneset_to_edit_111";
// add gene to set
const geneToAddToSet = "RER1";
const setToAddGeneTo = "fill_this_geneset";
// remove gene from set
const geneToRemove = "SIK1";
const setToRemoveFrom = "empty_this_geneset";
// brush a gene
const geneToBrushAndColorBy = "SIK1";
const brushThisGeneGeneset = "brush_this_gene";
const geneBrushedCellCount = "109";
const subsetGeneBrushedCellCount = "96";
async function setup(config) {
await goToPage(appUrlBase);
// setup the test fixtures
await createCategory(perTestCategoryName);
await createLabel(perTestCategoryName, perTestLabelName);
if (config.categoricalAnno) {
// 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 });
@@ -51,6 +95,166 @@ async function setup(config) {
describe.each([
{ withSubset: true, tag: "subset" },
{ withSubset: false, tag: "whole" },
])("geneSET crud operations and interactions", (config) => {
test("genesets load from csv", async () => {
await setup(config);
await assertGenesetExists(preExistingGenesetName);
});
test("brush on geneset mean", async () => {
await setup(config);
await expandGeneset(meanExpressionBrushGenesetName);
const histBrushableAreaId = `histogram-${meanExpressionBrushGenesetName}-plot-brushable-area`;
const coords = await calcDragCoordinates(histBrushableAreaId, {
x1: 0.25,
y1: 0.5,
x2: 0.55,
y2: 0.5,
});
await drag(histBrushableAreaId, coords.start, coords.end);
const cellCount = await getCellSetCount(1);
if (config.withSubset) {
expect(cellCount).toBe(subsetMeanExpressionBrushCellsSelected);
} else {
expect(cellCount).toBe(meanExpressionBrushCellsSelected);
}
});
test("color by mean expression", async () => {
await setup(config);
await colorByGeneset(meanExpressionBrushGenesetName);
await assertColorLegendLabel(meanExpressionBrushGenesetName);
});
test("diffexp", async () => {
if (config.withSubset) return;
await setup(config);
// set the two cell sets to b cells vs nk cells
await expandCategory(`louvain`);
await clickOn(`louvain:category-select`);
await clickOn(`categorical-value-select-louvain-B cells`);
await clickOn(`cellset-button-1`);
await clickOn(`categorical-value-select-louvain-B cells`);
await clickOn(`categorical-value-select-louvain-NK cells`);
await clickOn(`cellset-button-2`);
// run diffexp
await clickOn(`diffexp-button`);
await waitByClass("pop-1-geneset-expand");
await expect(page).toClick(getTestClass("pop-1-geneset-expand"));
await page.waitForFunction(
(selector) => !document.querySelector(selector),
{},
getTestClass("gene-loading-spinner")
);
let genesHTML = await getOneElementInnerHTML(
getTestClass("gene-set-genes")
);
expect(genesHTML).toMatchSnapshot();
await expect(page).toClick(getTestClass("pop-1-geneset-expand"));
await expect(page).toClick(getTestClass("pop-2-geneset-expand"));
await page.waitForFunction(
(selector) => !document.querySelector(selector),
{},
getTestClass("gene-loading-spinner")
);
genesHTML = await getOneElementInnerHTML(getTestClass("gene-set-genes"));
expect(genesHTML).toMatchSnapshot();
});
test("create a new geneset", async () => {
if (config.withSubset) return;
await setup(config);
const genesetName = `test-geneset-foo-123`;
await assertGenesetDoesNotExist(genesetName);
await createGeneset(genesetName);
/* note: as of June 2021, the aria label is in the truncate component which clones the element */
await assertGenesetExists(genesetName);
});
test("edit geneset name", async () => {
await setup(config);
await editGenesetName(editableGenesetName, editText);
await assertGenesetExists(newGenesetName);
});
test("delete a geneset", async () => {
if (config.withSubset) return;
await setup(config);
await deleteGeneset(genesetToDeleteName);
});
});
describe.each([
{ withSubset: true, tag: "subset" },
{ withSubset: false, tag: "whole" },
])("GENE crud operations and interactions", (config) => {
test("add a gene to geneset", async () => {
await setup(config);
await addGeneToSet(setToAddGeneTo, geneToAddToSet);
await expandGeneset(setToAddGeneTo);
await assertGeneExistsInGeneset(geneToAddToSet);
});
test("expand gene and brush", async () => {
await setup(config);
await expandGeneset(brushThisGeneGeneset);
await expandGene(geneToBrushAndColorBy);
const histBrushableAreaId = `histogram-${geneToBrushAndColorBy}-plot-brushable-area`;
const coords = await calcDragCoordinates(histBrushableAreaId, {
x1: 0.25,
y1: 0.5,
x2: 0.55,
y2: 0.5,
});
await drag(histBrushableAreaId, coords.start, coords.end);
const cellCount = await getCellSetCount(1);
if (config.withSubset) {
expect(cellCount).toBe(subsetGeneBrushedCellCount);
} else {
expect(cellCount).toBe(geneBrushedCellCount);
}
});
test("color by gene in geneset", async () => {
await setup(config);
await expandGeneset(meanExpressionBrushGenesetName);
await colorByGene(geneToBrushAndColorBy);
await assertColorLegendLabel(geneToBrushAndColorBy);
});
test("delete gene from geneset", async () => {
// We've already deleted the gene
if (config.withSubset) return;
await setup(config);
await expandGeneset(setToRemoveFrom);
await removeGene(geneToRemove);
await assertGeneDoesNotExist(geneToRemove);
});
});
describe.each([
{ withSubset: true, tag: "subset", categoricalAnno: true },
{ withSubset: false, tag: "whole", categoricalAnno: true },
])("annotations", (config) => {
test("create a category", async () => {
await setup(config);

View File

@@ -12,7 +12,7 @@ export async function waitByID(testId, props = {}) {
}
export async function waitByClass(testClass, props = {}) {
await page.waitForSelector(`[data-testclass='${testClass}']`, props);
return page.waitForSelector(`[data-testclass='${testClass}']`, props);
}
export async function waitForAllByIds(testIds) {

View File

@@ -366,6 +366,10 @@ class HistogramBrush extends React.PureComponent {
const fieldForId = field.replace(/\s/g, "_");
const showScatterPlot = isUserDefined;
let testClass = "histogram-continuous-metadata";
if (isUserDefined) testClass = "histogram-user-gene";
else if (isGeneSetSummary) testClass = "histogram-gene-set-summary";
return (
<Async
watchFn={HistogramBrush.watchAsync}
@@ -386,11 +390,7 @@ class HistogramBrush extends React.PureComponent {
<div
id={`histogram_${fieldForId}`}
data-testid={`histogram-${field}`}
data-testclass={
isUserDefined
? "histogram-user-gene"
: "histogram-continuous-metadata"
}
data-testclass={testClass}
style={{
padding: mini ? 0 : globals.leftSidebarSectionPadding,
backgroundColor: zebra ? globals.lightestGrey : "white",

View File

@@ -9,6 +9,7 @@ const StillLoading = ({ zebra, displayName }) => {
*/
return (
<div
data-testclass="gene-loading-spinner"
style={{
padding: globals.leftSidebarSectionPadding,
backgroundColor: zebra ? globals.lightestGrey : "white",

View File

@@ -98,6 +98,8 @@ const continuous = (selectorId, colorScale, colorAccessor) => {
.attr("y", 2)
.attr("x", 0 - legendHeight / 2)
.attr("dy", "1em")
.attr("data-testid", "continuous_legend_color_by_label")
.attr("aria-label", colorAccessor)
.style("text-anchor", "middle")
.style("fill", "white")
.text(colorAccessor);

View File

@@ -135,7 +135,7 @@ class Gene extends React.Component {
<Button
minimal
small
data-testid={`delete-from-geneset-${gene}`}
data-testid={`delete-from-geneset:${gene}`}
onClick={
quickGene ? removeGene(gene) : this.handleDeleteGeneFromSet
}

View File

@@ -10,6 +10,8 @@ import GenesetMenus from "./menus/genesetMenus";
import EditGenesetNameDialogue from "./menus/editGenesetNameDialogue";
import HistogramBrush from "../brushableHistogram";
import { diffexpPopNamePrefix1, diffexpPopNamePrefix2 } from "../../globals";
@connect((state, ownProps) => {
return {
world: state.world,
@@ -81,18 +83,22 @@ class GeneSet extends React.Component {
renderGenes() {
const { setName, setGenes, setGenesWithDescriptions } = this.props;
return setGenes.map((gene) => {
const { geneDescription } = setGenesWithDescriptions.get(gene);
return (
<div data-testclass="gene-set-genes">
{setGenes.map((gene) => {
const { geneDescription } = setGenesWithDescriptions.get(gene);
return (
<Gene
key={gene}
gene={gene}
geneDescription={geneDescription}
geneset={setName}
/>
);
});
return (
<Gene
key={gene}
gene={gene}
geneDescription={geneDescription}
geneset={setName}
/>
);
})}
</div>
);
}
render() {
@@ -100,6 +106,12 @@ class GeneSet extends React.Component {
const { isOpen } = this.state;
const genesetNameLengthVisible = 150; /* this magic number determines how much of a long geneset name we see */
const genesetIsEmpty = setGenes.length === 0;
let testClass = "geneset-expand";
if (setName.includes(diffexpPopNamePrefix1))
testClass = "pop-1-geneset-expand";
else if (setName.includes(diffexpPopNamePrefix2))
testClass = "pop-2-geneset-expand";
return (
<div style={{ marginBottom: 3 }}>
@@ -113,7 +125,7 @@ class GeneSet extends React.Component {
<span
role="menuitem"
tabIndex="0"
data-testclass="geneset-expand"
data-testclass={testClass}
data-testid={`${setName}:geneset-expand`}
onKeyPress={
/* TODO(colinmegill): #2101: click handler on span */ () => {}
@@ -133,7 +145,7 @@ class GeneSet extends React.Component {
style={{
maxWidth: globals.leftSidebarWidth - genesetNameLengthVisible,
}}
data-testid={`${setName}:geneset-label`}
data-testid={`${setName}:geneset-name`}
>
{setName}
</span>

View File

@@ -69,7 +69,7 @@ class GeneExpression extends React.Component {
<H4
role="menuitem"
tabIndex="0"
data-testclass="category-expand"
data-testclass="geneset-heading-expand"
onKeyPress={this.handleExpandGeneSets}
style={{
cursor: "pointer",

View File

@@ -58,7 +58,7 @@ class AddGeneToGenesetDialogue extends React.PureComponent {
isActive={genesetsUI.isAddingGenesToGeneset === geneset}
inputProps={{ "data-testid": `${geneset}:create-label-dialog` }}
primaryButtonProps={{
"data-testid": `${geneset}:submit-label`,
"data-testid": `${geneset}:submit-gene`,
}}
title="Add genes to gene set"
instruction={`Add genes to ${geneset}`}

View File

@@ -128,8 +128,8 @@ class CreateGenesetDialogue extends React.PureComponent {
};
render() {
const { genesetName, nameErrorMessage } = this.state;
const { metadataField, genesetsUI, genesets } = this.props;
const { genesetName, nameErrorMessage} = this.state;
const { genesetsUI, genesets } = this.props;
return (
<>
@@ -150,7 +150,7 @@ class CreateGenesetDialogue extends React.PureComponent {
<LabelInput
onChange={this.handleChange}
inputProps={{
"data-testid": "create-geneset-modal",
"data-testid": "create-geneset-input",
leftIcon: "manually-entered-data",
intent: "none",
autoFocus: true,
@@ -205,7 +205,7 @@ class CreateGenesetDialogue extends React.PureComponent {
</Button>
</Tooltip2>
<Button
data-testid={`${metadataField}:submit-geneset`}
data-testid="submit-geneset"
onClick={this.createGeneset}
disabled={nameErrorMessage !== ""}
intent="primary"

View File

@@ -55,7 +55,7 @@ class GenesetMenus extends React.PureComponent {
});
};
handleDeleteCategory = () => {
handleDeleteGeneset = () => {
const { dispatch, geneset } = this.props;
dispatch(actions.genesetDelete(geneset));
};
@@ -76,8 +76,8 @@ class GenesetMenus extends React.PureComponent {
>
<Button
style={{ marginLeft: 0, marginRight: 2 }}
data-testclass="handleAddNewLabelToCategory"
data-testid={`${geneset}:add-new-label-to-category`}
data-testclass="handleAddNewGeneToGeneset"
data-testid={`${geneset}:add-new-gene-to-geneset`}
icon={<Icon icon="plus" iconSize={10} />}
onClick={this.activateAddGeneToGenesetMode}
small
@@ -101,9 +101,9 @@ class GenesetMenus extends React.PureComponent {
<MenuItem
icon="trash"
intent="danger"
data-testclass="handleDeleteCategory"
data-testid={`${geneset}:delete-category`}
onClick={this.handleDeleteCategory}
data-testclass="handleDeleteGeneset"
data-testid={`${geneset}:delete-geneset`}
onClick={this.handleDeleteGeneset}
text="Delete this gene set (destructive, will remove set and collection of genes)"
/>
</Menu>

View File

@@ -122,7 +122,7 @@ function QuickGene() {
<H4
role="menuitem"
tabIndex="0"
data-testclass="category-expand"
data-testclass="quickgene-heading-expand"
onKeyPress={handleExpand}
style={{
cursor: "pointer",

View File

@@ -79,6 +79,9 @@ export const categoryDisplayStringMaxLength = 33;
export const maxUserDefinedGenes = 25;
export const maxGenes = 100;
export const diffexpPopNamePrefix1 = "Pop1 high";
export const diffexpPopNamePrefix2 = "Pop2 high";
/* various timing-related behaviors */
export const tooltipHoverOpenDelay = 1000; /* ms delay before a tooltip displays */
export const tooltipHoverOpenDelayQuick = 500;

View File

@@ -22,6 +22,8 @@
* routes. Do not rely on it to enforce geneset integrity - eg, no duplicate
* genes in a geneset.
*/
import { diffexpPopNamePrefix1, diffexpPopNamePrefix2 } from "../globals";
const GeneSets = (
state = {
initialized: false,
@@ -365,8 +367,8 @@ const GeneSets = (
const dateString = new Date().toLocaleString();
const genesetNames = {
positive: `Pop1 high (${dateString})`,
negative: `Pop2 high (${dateString})`,
positive: `${diffexpPopNamePrefix1} (${dateString})`,
negative: `${diffexpPopNamePrefix2} (${dateString})`,
};
const diffExpGeneSets = [];