Add undo/redo smoke tests for annotations (#1175)

* Add undo/redo tests for annotations

Fixes https://github.com/chanzuckerberg/cellxgene/issues/969

... also refactor the tests for DRY.

* Add done()

* Make e2e annotations tests safer to concurrency

* Add data-testclass for save state.

* Simplify tests and make them dependent on save state
This commit is contained in:
Matt Weiden
2020-02-26 12:10:03 -08:00
committed by GitHub
parent ded35c7252
commit 8a62c9f027
8 changed files with 254 additions and 101 deletions
+11 -4
View File
@@ -117,13 +117,20 @@ export const datasets = {
},
categoryLabel: {
lasso: {
"coordinates-as-percent": { x1: 0.3, y1: 0.3, x2: 0.5, y2: 0.5 },
count: "38"
"coordinates-as-percent": { x1: 0.05, y1: 0.3, x2: 0.5, y2: 0.5 },
},
newCount: {
bySubsetConfig: {
false: "199",
true: "193"
false: "600",
true: "591"
}
}
},
annotationsFromFile: {
count: {
bySubsetConfig: {
false: "1161",
true: "856"
}
}
},
+160 -64
View File
@@ -13,31 +13,19 @@ beforeAll(async () => {
[browser, page, utils, cxgActions] = await setupTestBrowser(browserViewport);
});
beforeEach(async () => {
await page.goto(appUrlBase);
});
afterAll(() => {
if (!DEBUG) browser.close();
});
describe("did launch", () => {
test("page launched", async () => {
let el = await utils.getOneElementInnerHTML("[data-testid='header']");
expect(el).toBe(data.title);
});
});
describe.each([
{withSubset: true},
{withSubset: false}
{withSubset: true, tag: "subset"},
{withSubset: false, tag: "whole"}
])("annotations", (config) => {
async function subset() {
const lassoSelection = await cxgActions.calcDragCoordinates(
"layout-graph",
{ x1: 0.10, y1: 0.10, x2: 0.80, y2: 0.80 }
{x1: 0.10, y1: 0.10, x2: 0.80, y2: 0.80}
);
await cxgActions.drag(
"layout-graph",
@@ -50,73 +38,76 @@ describe.each([
await cxgActions.clickOnCoordinate("layout-graph", coordinate);
}
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 cxgActions.createCategory(perTestCategoryName);
await cxgActions.createLabel(perTestCategoryName, perTestLabelName);
if (config.withSubset) await subset();
await utils.waitByClass("autosave-complete");
});
afterEach(async () => {
await deleteCategoryIfExists(perTestCategoryName);
await utils.waitByClass("autosave-complete");
});
test("create a category", async () => {
await utils.clickOn("open-annotation-dialog");
await utils.typeInto("new-category-name", "test-category-name");
await utils.clickOn("submit-category");
const result = await utils.waitByID("test-category-name:category-expand");
expect(await result.evaluate(node => node.innerText)).toBe("test-category-name");
const categoryName = `category-created-${config.tag}`;
await assertCategoryDoesNotExist(categoryName);
await cxgActions.createCategory(categoryName);
await assertCategoryExists(categoryName);
});
test("delete a category", async () => {
const previous = await utils.waitByID("cluster-test:category-expand");
expect(await previous.evaluate(node => node.innerText)).toBe("cluster-test");
await utils.hoverOn("cluster-test:see-actions");
await utils.clickOn("cluster-test:delete-category");
const result = await page.$("[data-testid='cluster-test:category-expand']");
expect(result).toBeNull();
await cxgActions.deleteCategory(perTestCategoryName);
await assertCategoryDoesNotExist(perTestCategoryName);
});
test("rename a category", async () => {
const previous = await utils.waitByID("cluster-test:category-expand");
expect(await previous.evaluate(node => node.innerText)).toBe("cluster-test");
await utils.hoverOn("cluster-test:see-actions");
await utils.clickOn("cluster-test:edit-category-mode");
await utils.typeInto("cluster-test:edit-category-name-text", "-renamed");
await utils.clickOn("cluster-test:submit-category-edit");
const result = await utils.waitByID("cluster-test-renamed:category-expand");
expect(await result.evaluate(node => node.innerText)).toBe("cluster-test-renamed");
const newCategoryName = `cluster-for-real-${config.tag}`;
await cxgActions.renameCategory(perTestCategoryName, newCategoryName);
await assertCategoryDoesNotExist(perTestCategoryName);
await assertCategoryExists(newCategoryName);
});
test("create a label", async () => {
await utils.hoverOn("cluster-test:see-actions");
await utils.clickOn("cluster-test:add-new-label-to-category");
await utils.typeInto("cluster-test:new-label-name", "test-label-name");
await utils.clickOn("cluster-test:submit-label");
await cxgActions.expandCategory("cluster-test");
const result = await utils.waitByID("categorical-value-cluster-test-test-label-name");
expect(await result.evaluate(node => node.innerText)).toBe("test-label-name");
const labelName = `new-label-${config.tag}`;
await assertLabelDoesNotExist(perTestCategoryName, labelName);
await cxgActions.createLabel(perTestCategoryName, labelName);
await assertLabelExists(perTestCategoryName, labelName);
});
test("delete a label", async () => {
await cxgActions.expandCategory("cluster-test");
const previous = await utils.waitByID("categorical-value-cluster-test-three");
expect(await previous.evaluate(node => node.innerText)).toBe("three");
await utils.hoverOn("cluster-test:three:see-actions");
await utils.clickOn("cluster-test:three:delete-label");
const result = await page.$("[data-testid='categorical-value-cluster-test-three']");
expect(result).toBeNull();
await cxgActions.deleteLabel(perTestCategoryName, perTestLabelName);
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
});
test("rename a label", async () => {
await cxgActions.expandCategory("cluster-test");
const previous = await utils.waitByID("categorical-value-cluster-test-four");
expect(await previous.evaluate(node => node.innerText)).toBe("four");
await utils.hoverOn("cluster-test:four:see-actions");
await utils.clickOn("cluster-test:four:edit-label");
await utils.typeInto("cluster-test:four:edit-label-name", ".");
await utils.clickOn("cluster-test:four:submit-label-edit");
const result = await utils.waitByID("categorical-value-cluster-test-four.");
expect(await result.evaluate(node => node.innerText)).toBe("four.");
const newLabelName = "my-cool-new-label";
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
await cxgActions.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 cxgActions.expandCategory(categoryName);
const result = await utils.waitByID(`categorical-value-count-${categoryName}-${labelName}`);
expect(await result.evaluate(node => node.innerText)).toBe(
data.annotationsFromFile.count.bySubsetConfig[config.withSubset]
);
});
test("assign cells to a label", async () => {
await cxgActions.expandCategory("cluster-test");
await cxgActions.expandCategory(perTestCategoryName);
const lassoSelection = await cxgActions.calcDragCoordinates(
"layout-graph",
data.categoryLabel.lasso["coordinates-as-percent"]
@@ -128,13 +119,118 @@ describe.each([
true
);
await utils.waitByID("lasso-element", {visible: true});
const initialCount = await cxgActions.cellSet(1);
expect(initialCount).toBe(data.categoryLabel.lasso.count);
await utils.hoverOn("cluster-test:one:see-actions");
await utils.clickOn("cluster-test:one:add-current-selection-to-this-label");
const result = await utils.waitByID("categorical-value-count-cluster-test-one");
await utils.clickOn(`${perTestCategoryName}:${perTestLabelName}:see-actions`);
await utils.clickOn(`${perTestCategoryName}:${perTestLabelName}:add-current-selection-to-this-label`);
const result = await utils.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 () => {
const categoryName = `category-created-undo-${config.tag}`;
await assertCategoryDoesNotExist(categoryName);
await cxgActions.createCategory(categoryName);
await assertCategoryExists(categoryName);
await utils.clickOn("undo");
await assertCategoryDoesNotExist(categoryName);
await utils.clickOn("redo");
await assertCategoryExists(categoryName);
});
test("undo/redo category deletion", async () => {
const categoryName = `category-deleted-undo-${config.tag}`;
await cxgActions.createCategory(categoryName);
await assertCategoryExists(categoryName);
await cxgActions.deleteCategory(categoryName);
await assertCategoryDoesNotExist(categoryName);
await utils.clickOn("undo");
await assertCategoryExists(categoryName);
await utils.clickOn("redo");
await assertCategoryDoesNotExist(categoryName);
});
test("undo/redo category rename", async () => {
const newCategoryName = `category-renamed-undo-${config.tag}`;
await assertCategoryDoesNotExist(newCategoryName);
await cxgActions.renameCategory(perTestCategoryName, newCategoryName);
await assertCategoryExists(newCategoryName);
await assertCategoryDoesNotExist(perTestCategoryName);
await utils.clickOn("undo");
await assertCategoryExists(perTestCategoryName);
await assertCategoryDoesNotExist(newCategoryName);
await utils.clickOn("redo");
await assertCategoryExists(newCategoryName);
await assertCategoryDoesNotExist(perTestCategoryName);
});
test("undo/redo label creation", async () => {
const labelName = `label-created-undo-${config.tag}`;
await assertLabelDoesNotExist(perTestCategoryName, labelName);
await cxgActions.createLabel(perTestCategoryName, labelName);
await assertLabelExists(perTestCategoryName, labelName);
await utils.clickOn("undo");
await assertLabelDoesNotExist(perTestCategoryName);
await utils.clickOn("redo");
await assertLabelExists(perTestCategoryName, labelName);
});
test("undo/redo label deletion", async () => {
await cxgActions.deleteLabel(perTestCategoryName, perTestLabelName);
await assertLabelDoesNotExist(perTestCategoryName);
await utils.clickOn("undo");
await assertLabelExists(perTestCategoryName, perTestLabelName);
await utils.clickOn("redo");
await assertLabelDoesNotExist(perTestCategoryName);
});
test("undo/redo label rename", async () => {
const newLabelName = `label-renamed-undo-${config.tag}`;
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
await cxgActions.renameLabel(perTestCategoryName, perTestLabelName, newLabelName);
await assertLabelExists(perTestCategoryName, newLabelName);
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
await utils.clickOn("undo");
await assertLabelExists(perTestCategoryName, perTestLabelName);
await assertLabelDoesNotExist(perTestCategoryName, newLabelName);
await utils.clickOn("redo");
await assertLabelExists(perTestCategoryName, newLabelName);
await assertLabelDoesNotExist(perTestCategoryName, perTestLabelName);
});
async function assertCategoryExists(categoryName) {
const result = await utils.waitByID(`${categoryName}:category-expand`);
expect(await result.evaluate(node => node.innerText)).toBe(categoryName);
}
async function assertCategoryDoesNotExist(categoryName) {
const result = await page.$(`[data-testid='${categoryName}:category-expand']`);
expect(result).toBeNull();
}
async function assertLabelExists(categoryName, labelName) {
const category = await utils.waitByID(`${categoryName}:category-expand`);
expect(category).not.toBeNull();
await cxgActions.expandCategory(categoryName);
const previous = await utils.waitByID(`categorical-value-${categoryName}-${labelName}`);
expect(await previous.evaluate(node => node.innerText)).toBe(labelName);
}
async function assertLabelDoesNotExist(categoryName, labelName) {
await cxgActions.expandCategory(categoryName);
const result = await page.$(`[data-testid='categorical-value-${categoryName}-${labelName}']`);
expect(result).toBeNull();
}
async function deleteCategoryIfExists(categoryName) {
try {
const category = await page.waitForSelector(
`[data-testid='${categoryName}:category-expand']`,
{timeout: 200}
);
if (category !== null) return await cxgActions.deleteCategory(categoryName);
} catch (error) {
}
return null
}
});
+49 -11
View File
@@ -56,19 +56,13 @@ export const puppeteerUtils = puppeteerPage => ({
// select all
await puppeteerPage.click(selector, { clickCount: 3 });
await puppeteerPage.keyboard.type("Backspace");
await puppeteerPage.keyboard.press("Backspace");
await puppeteerPage.type(selector, text);
},
async clickOn(testid) {
async clickOn(testid, options={}) {
await this.waitByID(testid);
await puppeteerPage.click(`[data-testid='${testid}']`);
await puppeteerPage.waitFor(50);
},
async hoverOn(testid) {
await this.waitByID(testid);
await puppeteerPage.hover(`[data-testid='${testid}']`);
await puppeteerPage.click(`[data-testid='${testid}']`, options);
await puppeteerPage.waitFor(50);
},
@@ -210,8 +204,10 @@ export const cellxgeneActions = puppeteerPage => ({
async expandCategory(category) {
const expand = await puppeteerUtils(puppeteerPage).waitByID(`${category}:category-expand`);
const expandArrow = await expand.$("[data-testclass='category-expand-is-not-expanded']");
await expandArrow.click();
const notExpanded = await expand.$("[data-testclass='category-expand-is-not-expanded']");
if (notExpanded) {
await puppeteerUtils(puppeteerPage).clickOn(`${category}:category-expand`);
}
},
async reset() {
@@ -231,6 +227,48 @@ export const cellxgeneActions = puppeteerPage => ({
max
);
await puppeteerUtils(puppeteerPage).clickOn("clip-commit");
},
async createCategory(categoryName) {
await puppeteerUtils(puppeteerPage).clickOn("open-annotation-dialog");
await puppeteerUtils(puppeteerPage).typeInto("new-category-name", categoryName);
await puppeteerUtils(puppeteerPage).clickOn("submit-category");
},
async renameCategory(oldCatgoryName, newCategoryName) {
await puppeteerUtils(puppeteerPage).clickOn(`${oldCatgoryName}:see-actions`);
await puppeteerUtils(puppeteerPage).clickOn(`${oldCatgoryName}:edit-category-mode`);
await puppeteerUtils(puppeteerPage).clearInputAndTypeInto(`${oldCatgoryName}:edit-category-name-text`, newCategoryName);
await puppeteerUtils(puppeteerPage).clickOn(`${oldCatgoryName}:submit-category-edit`);
},
async deleteCategory(categoryName) {
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:see-actions`);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:delete-category`);
},
async createLabel(categoryName, labelName) {
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:see-actions`);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:add-new-label-to-category`);
await puppeteerUtils(puppeteerPage).typeInto(`${categoryName}:new-label-name`, labelName);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:submit-label`);
},
async deleteLabel(categoryName, labelName) {
await this.expandCategory(categoryName);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:${labelName}:see-actions`);
await puppeteerUtils(puppeteerPage).clickOn( `${categoryName}:${labelName}:delete-label`);
},
async renameLabel(categoryName, oldLabelName, newLabelName) {
await this.expandCategory(categoryName);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:${oldLabelName}:see-actions`);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:${oldLabelName}:edit-label`);
await puppeteerUtils(puppeteerPage).clearInputAndTypeInto(
`${categoryName}:${oldLabelName}:edit-label-name`,
newLabelName
);
await puppeteerUtils(puppeteerPage).clickOn(`${categoryName}:${oldLabelName}:submit-label-edit`);
}
});
+10 -2
View File
@@ -11,7 +11,8 @@ import FilenameDialog from "./filenameDialog";
saveInProgress: state.autosave?.saveInProgress ?? false,
lastSavedObsAnnotations: state.autosave?.lastSavedObsAnnotations,
error: state.autosave?.error,
writableCategoriesEnabled: state.config?.parameters?.["annotations"] ?? false
writableCategoriesEnabled: state.config?.parameters?.["annotations"] ?? false,
initialDataLoadComplete: state.autosave?.initialDataLoadComplete
}))
class Autosave extends React.Component {
constructor(props) {
@@ -63,10 +64,17 @@ class Autosave extends React.Component {
}
render() {
const { writableCategoriesEnabled } = this.props;
const { writableCategoriesEnabled, saveInProgress, initialDataLoadComplete } = this.props;
return writableCategoriesEnabled ? (
<div
id="autosave"
data-testclass={
!initialDataLoadComplete
? "autosave-init"
: (this.needToSave() || saveInProgress)
? "autosave-incomplete"
: "autosave-complete"
}
style={{
position: "fixed",
display: "inherit",
@@ -29,6 +29,7 @@ function InformationMenu(props) {
style={{
cursor: "pointer"
}}
data-testid="undo"
/>
</Tooltip>
<Tooltip
@@ -46,6 +47,7 @@ function InformationMenu(props) {
style={{
cursor: "pointer"
}}
data-testid="redo"
/>
</Tooltip>
<Tooltip
+4 -2
View File
@@ -2,7 +2,8 @@ const Autosave = (
state = {
saveInProgress: false,
error: false,
lastSavedObsAnnotations: null
lastSavedObsAnnotations: null,
initialDataLoadComplete: false
},
action,
nextSharedState
@@ -15,7 +16,8 @@ const Autosave = (
...state,
error: false,
saveInProgress: false,
lastSavedObsAnnotations: universe.obsAnnotations
lastSavedObsAnnotations: universe.obsAnnotations,
initialDataLoadComplete: true,
};
}
+1 -1
View File
@@ -272,7 +272,7 @@ class EndPointsAnnotations(EndPoints):
def test_get_user_annotations_existing_obs_keys_fbs(self):
self._test_get_user_annotations_obs_keys_fbs(
"cluster-test", {"unassigned", "one", "two", "three", "four", "five"},
"cluster-test", {"unassigned", "one", "two", "three", "four", "five", "six", "seven"},
)
def test_put_user_annotations_obs_fbs(self):
@@ -1,5 +1,5 @@
# Annotations generated on 2020-02-07T16:48:13 using cellxgene version 0.14.0
# Input data file was ../example-dataset/pbmc3k.h5ad, which was last modified on 2019-12-17T17:13:17
# Annotations generated on 2020-02-24T23:19:31 using cellxgene version 0.14.0
# Input data file was example-dataset/pbmc3k.h5ad, which was last modified on 2019-12-17T17:13:17
index,cluster-test
AAACATACAACCAC-1,four
AAACATTGAGCTAC-1,three
@@ -27,7 +27,7 @@ AAAGTTTGTAGCGT-1,two
AAATCAACAATGCC-1,three
AAATCAACACCAGT-1,four
AAATCAACCAGGAG-1,four
AAATCAACCCTATT-1,unassigned
AAATCAACCCTATT-1,seven
AAATCAACGGAAGC-1,four
AAATCAACTCGCAA-1,four
AAATCATGACCACA-1,one
@@ -245,7 +245,7 @@ ACCCAAGAGGACAG-1,four
ACCCAAGATTCACT-1,three
ACCCACTGCGCCTT-1,two
ACCCACTGGACAGG-1,four
ACCCACTGGTTCAG-1,one
ACCCACTGGTTCAG-1,six
ACCCACTGTCGTAG-1,two
ACCCAGCTCAGAAA-1,four
ACCCAGCTGTTAGC-1,two
@@ -271,7 +271,7 @@ ACCTTTGACTCCCA-1,two
ACCTTTGAGGAACG-1,two
ACCTTTGAGGAAGC-1,one
ACGAACACCTTGTT-1,five
ACGAACTGGCTATG-1,one
ACGAACTGGCTATG-1,six
ACGAAGCTCTCCAC-1,four
ACGAAGCTCTGAGT-1,three
ACGACCCTATCTCT-1,one
@@ -545,7 +545,7 @@ AGTCTACTAGGGTG-1,two
AGTCTACTTGCATG-1,one
AGTCTTACACCACA-1,four
AGTCTTACTTCGCC-1,five
AGTCTTACTTCGGA-1,one
AGTCTTACTTCGGA-1,six
AGTGACTGCAACTG-1,one
AGTGTTCTAACCTG-1,four
AGTGTTCTATAAGG-1,four
@@ -630,7 +630,7 @@ ATCAACCTTCTCTA-1,five
ATCAACCTTTGTCT-1,five
ATCACACTTTGTCT-1,four
ATCACGGATTTCGT-1,three
ATCATCTGACACCA-1,one
ATCATCTGACACCA-1,six
ATCATGCTAGAGTA-1,five
ATCATGCTGAACCT-1,three
ATCCAGGACGCTAA-1,one
@@ -745,7 +745,7 @@ ATTAGATGTTTCAC-1,four
ATTATGGAATCTCT-1,four
ATTCAAGAACGGGA-1,four
ATTCAAGACCTTTA-1,four
ATTCAGCTCATTGG-1,one
ATTCAGCTCATTGG-1,six
ATTCCAACCATTGG-1,two
ATTCCAACTTAGGC-1,five
ATTCGACTCACTAG-1,four
@@ -946,7 +946,7 @@ CATAACCTTCTCCG-1,four
CATACTACCTCGAA-1,four
CATACTACCTGAAC-1,four
CATACTACGTACCA-1,two
CATACTTGGGTTAC-1,four
CATACTTGGGTTAC-1,seven
CATAGTCTAATCGC-1,four
CATAGTCTCACTTT-1,four
CATATAGACTAAGC-1,unassigned
@@ -1523,7 +1523,7 @@ GACCTCTGCATCAG-1,four
GACGAACTCCCACT-1,four
GACGATTGCCAATG-1,three
GACGCCGACCTTCG-1,four
GACGCTCTCTCTCG-1,one
GACGCTCTCTCTCG-1,six
GACGGCACACGGGA-1,five
GACGGCACGAGATA-1,two
GACGTAACCTATGG-1,four
@@ -1589,7 +1589,7 @@ GAGTGTTGTGGTCA-1,four
GAGTTGTGCATGGT-1,unassigned
GAGTTGTGCTGAGT-1,five
GAGTTGTGGCGAGA-1,two
GAGTTGTGGTAGCT-1,one
GAGTTGTGGTAGCT-1,six
GAGTTGTGTATGCG-1,one
GATAAGGAGAAACA-1,two
GATAAGGATTCACT-1,two
@@ -1735,7 +1735,7 @@ GCGATATGGTGTTG-1,four
GCGCACGAAGTCGT-1,four
GCGCACGACTTTAC-1,two
GCGCATCTAGGTCT-1,four
GCGCATCTGGTTAC-1,one
GCGCATCTGGTTAC-1,six
GCGCATCTTCGATG-1,four
GCGCATCTTGCTCC-1,five
GCGCATCTTTCTAC-1,four
@@ -1779,7 +1779,7 @@ GCTTAACTGCTGAT-1,four
GCTTAACTTAGACC-1,two
GCTTAACTTCAGTG-1,four
GGAACACTCACTTT-1,two
GGAACACTTCAGAC-1,one
GGAACACTTCAGAC-1,six
GGAACTACTACTTC-1,four
GGAACTTGAAGGTA-1,two
GGAACTTGAGAATG-1,four
@@ -1841,7 +1841,7 @@ GGCAATACGTTTCT-1,three
GGCACGTGGCTTAG-1,one
GGCACTCTTTTGTC-1,four
GGCATATGCTTATC-1,five
GGCATATGGGGAGT-1,one
GGCATATGGGGAGT-1,six
GGCATATGTGTGAC-1,unassigned
GGCCACGACAGAGG-1,four
GGCCAGACTGGTTG-1,four
@@ -1977,7 +1977,7 @@ GTCACCTGCCTCCA-1,four
GTCACCTGTCCCGT-1,four
GTCATACTAATCGC-1,three
GTCATACTGCGATT-1,five
GTCATACTTCGCCT-1,one
GTCATACTTCGCCT-1,six
GTCATACTTTACCT-1,five
GTCATACTTTGACG-1,four
GTCCAAGAAAAACG-1,four
@@ -2044,7 +2044,7 @@ TAAATCGATGAGGG-1,four
TAACAATGTGCCCT-1,three
TAACACCTTCGCTC-1,two
TAACACCTTCGTAG-1,two
TAACACCTTGTTTC-1,one
TAACACCTTGTTTC-1,six
TAACATGACACTAG-1,three
TAACCGGACTTACT-1,four
TAACGTCTCAACCA-1,two
@@ -2507,7 +2507,7 @@ TTACCATGTGTCTT-1,four
TTACCATGTTGTGG-1,three
TTACGACTGAGAGC-1,four
TTACGACTTGACAC-1,two
TTACGTACGTTCAG-1,one
TTACGTACGTTCAG-1,six
TTACTCGAAGAATG-1,two
TTACTCGACGCAAT-1,unassigned
TTACTCGAGGGTGA-1,four
1 # Annotations generated on 2020-02-07T16:48:13 using cellxgene version 0.14.0 # Annotations generated on 2020-02-24T23:19:31 using cellxgene version 0.14.0
2 # Input data file was ../example-dataset/pbmc3k.h5ad, which was last modified on 2019-12-17T17:13:17 # Input data file was example-dataset/pbmc3k.h5ad, which was last modified on 2019-12-17T17:13:17
3 index,cluster-test
4 AAACATACAACCAC-1,four
5 AAACATTGAGCTAC-1,three
27 AAATCAACAATGCC-1,three
28 AAATCAACACCAGT-1,four
29 AAATCAACCAGGAG-1,four
30 AAATCAACCCTATT-1,unassigned AAATCAACCCTATT-1,seven
31 AAATCAACGGAAGC-1,four
32 AAATCAACTCGCAA-1,four
33 AAATCATGACCACA-1,one
245 ACCCAAGATTCACT-1,three
246 ACCCACTGCGCCTT-1,two
247 ACCCACTGGACAGG-1,four
248 ACCCACTGGTTCAG-1,one ACCCACTGGTTCAG-1,six
249 ACCCACTGTCGTAG-1,two
250 ACCCAGCTCAGAAA-1,four
251 ACCCAGCTGTTAGC-1,two
271 ACCTTTGAGGAACG-1,two
272 ACCTTTGAGGAAGC-1,one
273 ACGAACACCTTGTT-1,five
274 ACGAACTGGCTATG-1,one ACGAACTGGCTATG-1,six
275 ACGAAGCTCTCCAC-1,four
276 ACGAAGCTCTGAGT-1,three
277 ACGACCCTATCTCT-1,one
545 AGTCTACTTGCATG-1,one
546 AGTCTTACACCACA-1,four
547 AGTCTTACTTCGCC-1,five
548 AGTCTTACTTCGGA-1,one AGTCTTACTTCGGA-1,six
549 AGTGACTGCAACTG-1,one
550 AGTGTTCTAACCTG-1,four
551 AGTGTTCTATAAGG-1,four
630 ATCAACCTTTGTCT-1,five
631 ATCACACTTTGTCT-1,four
632 ATCACGGATTTCGT-1,three
633 ATCATCTGACACCA-1,one ATCATCTGACACCA-1,six
634 ATCATGCTAGAGTA-1,five
635 ATCATGCTGAACCT-1,three
636 ATCCAGGACGCTAA-1,one
745 ATTATGGAATCTCT-1,four
746 ATTCAAGAACGGGA-1,four
747 ATTCAAGACCTTTA-1,four
748 ATTCAGCTCATTGG-1,one ATTCAGCTCATTGG-1,six
749 ATTCCAACCATTGG-1,two
750 ATTCCAACTTAGGC-1,five
751 ATTCGACTCACTAG-1,four
946 CATACTACCTCGAA-1,four
947 CATACTACCTGAAC-1,four
948 CATACTACGTACCA-1,two
949 CATACTTGGGTTAC-1,four CATACTTGGGTTAC-1,seven
950 CATAGTCTAATCGC-1,four
951 CATAGTCTCACTTT-1,four
952 CATATAGACTAAGC-1,unassigned
1523 GACGAACTCCCACT-1,four
1524 GACGATTGCCAATG-1,three
1525 GACGCCGACCTTCG-1,four
1526 GACGCTCTCTCTCG-1,one GACGCTCTCTCTCG-1,six
1527 GACGGCACACGGGA-1,five
1528 GACGGCACGAGATA-1,two
1529 GACGTAACCTATGG-1,four
1589 GAGTTGTGCATGGT-1,unassigned
1590 GAGTTGTGCTGAGT-1,five
1591 GAGTTGTGGCGAGA-1,two
1592 GAGTTGTGGTAGCT-1,one GAGTTGTGGTAGCT-1,six
1593 GAGTTGTGTATGCG-1,one
1594 GATAAGGAGAAACA-1,two
1595 GATAAGGATTCACT-1,two
1735 GCGCACGAAGTCGT-1,four
1736 GCGCACGACTTTAC-1,two
1737 GCGCATCTAGGTCT-1,four
1738 GCGCATCTGGTTAC-1,one GCGCATCTGGTTAC-1,six
1739 GCGCATCTTCGATG-1,four
1740 GCGCATCTTGCTCC-1,five
1741 GCGCATCTTTCTAC-1,four
1779 GCTTAACTTAGACC-1,two
1780 GCTTAACTTCAGTG-1,four
1781 GGAACACTCACTTT-1,two
1782 GGAACACTTCAGAC-1,one GGAACACTTCAGAC-1,six
1783 GGAACTACTACTTC-1,four
1784 GGAACTTGAAGGTA-1,two
1785 GGAACTTGAGAATG-1,four
1841 GGCACGTGGCTTAG-1,one
1842 GGCACTCTTTTGTC-1,four
1843 GGCATATGCTTATC-1,five
1844 GGCATATGGGGAGT-1,one GGCATATGGGGAGT-1,six
1845 GGCATATGTGTGAC-1,unassigned
1846 GGCCACGACAGAGG-1,four
1847 GGCCAGACTGGTTG-1,four
1977 GTCACCTGTCCCGT-1,four
1978 GTCATACTAATCGC-1,three
1979 GTCATACTGCGATT-1,five
1980 GTCATACTTCGCCT-1,one GTCATACTTCGCCT-1,six
1981 GTCATACTTTACCT-1,five
1982 GTCATACTTTGACG-1,four
1983 GTCCAAGAAAAACG-1,four
2044 TAACAATGTGCCCT-1,three
2045 TAACACCTTCGCTC-1,two
2046 TAACACCTTCGTAG-1,two
2047 TAACACCTTGTTTC-1,one TAACACCTTGTTTC-1,six
2048 TAACATGACACTAG-1,three
2049 TAACCGGACTTACT-1,four
2050 TAACGTCTCAACCA-1,two
2507 TTACCATGTTGTGG-1,three
2508 TTACGACTGAGAGC-1,four
2509 TTACGACTTGACAC-1,two
2510 TTACGTACGTTCAG-1,one TTACGTACGTTCAG-1,six
2511 TTACTCGAAGAATG-1,two
2512 TTACTCGACGCAAT-1,unassigned
2513 TTACTCGAGGGTGA-1,four