Smoke tests (#604)

smoke tests
This commit is contained in:
Charlotte Weaver
2019-02-27 15:46:58 -08:00
committed by GitHub
parent 6b33315cbe
commit 2bae696986
11 changed files with 555 additions and 10 deletions

View File

@@ -12,10 +12,18 @@ install:
- make install
- pip install -r server/requirements-dev.txt
- docker build .
script:
- set -eo pipefail
- flake8 server
- black --check
- npm run --prefix client/ build
- npm run --prefix client/ test
- pytest -s server/test
jobs:
include:
- name: "Branch Tests"
script:
- set -eo pipefail
- flake8 server
- black --check
- npm run --prefix client/ build
- npm run --prefix client/ unit-test
- pytest -s server/test
- name: "Smoke Tests"
if: branch = master AND type = cron
script:
- npm run --prefix client/ smoke-test

View File

@@ -0,0 +1,185 @@
import puppeteer from "puppeteer";
const jest_env = process.env.JEST_ENV || "dev";
const appPort = process.env.JEST_CXG_PORT || 3000;
const appUrlBase = `http://localhost:${appPort}`;
const DEV = jest_env === "dev";
let browser;
let page;
const browserViewport = { width: 1280, height: 960 };
beforeAll(async () => {
const browser_params = DEV
? { headless: false, slowMo: 100, devtools: true }
: {};
browser = await puppeteer.launch(browser_params);
page = await browser.newPage();
page.setViewport(browserViewport);
if (DEV) page.on("console", msg => console.log("PAGE LOG:", msg.text()));
});
afterAll(() => {
if (!DEV) {
browser.close();
}
});
const getOneElementInnerHTML = async function(selector) {
let text = await page.$eval(selector, el => el.innerHTML);
return text;
};
const drag = async function(el_box, start, end, lasso = false) {
const x1 = el_box.content[0].x + start.x;
const x2 = el_box.content[0].x + end.x;
const y1 = el_box.content[0].y + start.y;
const y2 = el_box.content[0].y + end.y;
await page.mouse.move(x1, y1);
await page.mouse.down();
if (lasso) {
await page.mouse.move(x2, y1);
await page.mouse.move(x2, y2);
await page.mouse.move(x1, y2);
await page.mouse.move(x1, y1);
} else {
await page.mouse.move(x2, y2);
}
await page.mouse.up();
};
describe("did launch", () => {
test("page launched", async () => {
await page.goto(appUrlBase);
let el = await getOneElementInnerHTML("[data-testid='header']");
expect(el).toBe("cellxgene: pbmc3k");
});
});
describe("search for genes", () => {
test("search for known gene and add to metadata", async () => {
await page.goto(appUrlBase);
await page.waitForSelector("[ data-testid='gene-search']");
// blueprint's typeahead is treating typing weird, clicking & waiting first solves this
await page.click("[data-testid='gene-search']");
await page.waitFor(200);
await page.type("[data-testid='gene-search']", "ACD");
await page.keyboard.press("Enter");
await page.waitForSelector("[data-testid='histogram-ACD']");
});
});
describe("select cells and diffexp", () => {
test("selects cells from layout and adds to cell set 1", async () => {
await page.goto(appUrlBase);
const layout = await page.waitForSelector("[data-testid='layout']");
const size = await layout.boxModel();
const cellset1 = {
start: {
x: Math.floor(size.width * 0.25),
y: Math.floor(size.height * 0.25)
},
end: {
x: Math.floor(size.width * 0.35),
y: Math.floor(size.height * 0.35)
}
};
await drag(size, cellset1.start, cellset1.end, true);
await page.click("[data-testid='cellset-button-1");
let button = await getOneElementInnerHTML("[data-testid='cellset-button-1");
expect(button).toMatch(/26 cells/);
});
test("selects cells from layout and adds to cell set 2", async () => {
await page.goto(appUrlBase);
const layout = await page.waitForSelector("[data-testid='layout']");
const size = await layout.boxModel();
const cellset2 = {
start: {
x: Math.floor(size.width * 0.45),
y: Math.floor(size.height * 0.45)
},
end: {
x: Math.floor(size.width * 0.55),
y: Math.floor(size.height * 0.55)
}
};
await drag(size, cellset2.start, cellset2.end, true);
await page.click("[data-testid='cellset-button-2");
let button = await getOneElementInnerHTML("[data-testid='cellset-button-2");
expect(button).toMatch(/49 cells/);
});
test("selects cells, saves them and performs diffexp", async () => {
await page.goto(appUrlBase);
const layout = await page.waitForSelector("[data-testid='layout']");
const size = await layout.boxModel();
const cellset1 = {
start: {
x: Math.floor(size.width * 0.25),
y: Math.floor(size.height * 0.25)
},
end: {
x: Math.floor(size.width * 0.35),
y: Math.floor(size.height * 0.35)
}
};
await drag(size, cellset1.start, cellset1.end, true);
await page.click("[data-testid='cellset-button-1");
const cellset2 = {
start: {
x: Math.floor(size.width * 0.45),
y: Math.floor(size.height * 0.45)
},
end: {
x: Math.floor(size.width * 0.55),
y: Math.floor(size.height * 0.55)
}
};
await drag(size, cellset2.start, cellset2.end, true);
await page.click("[data-testid='cellset-button-2");
await page.click("[data-testid='diffexp-button");
await page.waitForSelector("[data-testclass='histogram-diffexp']");
const diffexps = await page.$$eval(
"[data-testclass='histogram-diffexp']",
divs => {
return divs.map(div =>
div.id.substring("histogram-".length, div.id.length)
);
}
);
expect(diffexps).toMatchObject([
"HLA-DPA1",
"HLA-DQA1",
"HLA-DRB1",
"HLA-DMA",
"CST3",
"HLA-DPB1",
"HLA-DQB1",
"LGALS2",
"FCER1A",
"LTB"
]);
});
});
describe("brushable histogram", () => {
test("can brush historgram", async () => {
await page.goto(appUrlBase);
const hist = await page.waitForSelector(
"[data-testid='histogram_n_genes_svg-brush'] > .overlay"
);
const hist_size = await hist.boxModel();
const draghist = {
start: {
x: Math.floor(hist_size.width * 0.25),
y: Math.floor(hist_size.height * 0.5)
},
end: {
x: Math.floor(hist_size.width * 0.55),
y: Math.floor(hist_size.height * 0.5)
}
};
await drag(hist_size, draghist.start, draghist.end);
});
});

337
client/package-lock.json generated
View File

@@ -1296,6 +1296,15 @@
"integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
"dev": true
},
"agent-base": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
"dev": true,
"requires": {
"es6-promisify": "^5.0.0"
}
},
"ajv": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz",
@@ -2807,6 +2816,12 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
},
"check-more-types": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
"integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=",
"dev": true
},
"chokidar": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
@@ -4118,6 +4133,12 @@
"is-obj": "^1.0.0"
}
},
"duplexer": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
@@ -4278,6 +4299,15 @@
"integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
"dev": true
},
"es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
"es6-promise": "^4.0.3"
}
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -4767,6 +4797,21 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
"event-stream": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
"integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
"dev": true,
"requires": {
"duplexer": "~0.1.1",
"from": "~0",
"map-stream": "~0.1.0",
"pause-stream": "0.0.11",
"split": "0.3",
"stream-combiner": "~0.0.4",
"through": "~2.3.1"
}
},
"events": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
@@ -4963,6 +5008,35 @@
"is-extglob": "^1.0.0"
}
},
"extract-zip": {
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
"dev": true,
"requires": {
"concat-stream": "1.6.2",
"debug": "2.6.9",
"mkdirp": "0.5.1",
"yauzl": "2.4.1"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
}
}
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
@@ -5023,6 +5097,15 @@
}
}
},
"fd-slicer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
"dev": true,
"requires": {
"pend": "~1.2.0"
}
},
"figures": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
@@ -5229,6 +5312,12 @@
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
"dev": true
},
"from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
"dev": true
},
"from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
@@ -6127,6 +6216,12 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
"hoek": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz",
"integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==",
"dev": true
},
"hoist-non-react-statics": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.1.0.tgz",
@@ -6295,6 +6390,16 @@
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
"dev": true
},
"https-proxy-agent": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
"dev": true,
"requires": {
"agent-base": "^4.1.0",
"debug": "^3.1.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -6825,6 +6930,15 @@
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"dev": true
},
"isemail": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz",
"integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==",
"dev": true,
"requires": {
"punycode": "2.x.x"
}
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -9078,6 +9192,17 @@
}
}
},
"joi": {
"version": "13.7.0",
"resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz",
"integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==",
"dev": true,
"requires": {
"hoek": "5.x.x",
"isemail": "3.x.x",
"topo": "3.x.x"
}
},
"js-levenshtein": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz",
@@ -9240,6 +9365,12 @@
"package-json": "^4.0.0"
}
},
"lazy-ass": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
"integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=",
"dev": true
},
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
@@ -9521,6 +9652,12 @@
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"dev": true
},
"map-stream": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
"integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
"dev": true
},
"map-visit": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
@@ -10533,6 +10670,15 @@
}
}
},
"pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
"dev": true,
"requires": {
"through": "~2.3"
}
},
"pbkdf2": {
"version": "3.0.17",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
@@ -10546,6 +10692,12 @@
"sha.js": "^2.4.8"
}
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -10791,12 +10943,27 @@
"ipaddr.js": "1.8.0"
}
},
"proxy-from-env": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=",
"dev": true
},
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true
},
"ps-tree": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
"integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
"dev": true,
"requires": {
"event-stream": "=3.3.4"
}
},
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -10850,6 +11017,48 @@
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"puppeteer": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.12.2.tgz",
"integrity": "sha512-xWSyCeD6EazGlfnQweMpM+Hs6X6PhUYhNTHKFj/axNZDq4OmrVERf70isBf7HsnFgB3zOC1+23/8+wCAZYg+Pg==",
"dev": true,
"requires": {
"debug": "^4.1.0",
"extract-zip": "^1.6.6",
"https-proxy-agent": "^2.2.1",
"mime": "^2.0.3",
"progress": "^2.0.1",
"proxy-from-env": "^1.0.0",
"rimraf": "^2.6.1",
"ws": "^6.1.0"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"mime": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz",
"integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==",
"dev": true
},
"ws": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
"integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
"dev": true,
"requires": {
"async-limiter": "~1.0.0"
}
}
}
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
@@ -11817,6 +12026,12 @@
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
"integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
},
"rx": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
"integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
"dev": true
},
"rxjs": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
@@ -12637,6 +12852,15 @@
"integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==",
"dev": true
},
"split": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
"integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
"dev": true,
"requires": {
"through": "2"
}
},
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
@@ -12684,6 +12908,63 @@
"integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==",
"dev": true
},
"start-server-and-test": {
"version": "1.7.11",
"resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.7.11.tgz",
"integrity": "sha512-651SCOfhPT65Xjhecvx/ZMJs8UOd5VItjjmpYH95aM6Hr4P8N8UIcxEgDhY/aaVmthACH7qFTqs4EA/KHykjtw==",
"dev": true,
"requires": {
"bluebird": "3.5.3",
"check-more-types": "2.24.0",
"debug": "3.2.6",
"execa": "0.11.0",
"lazy-ass": "1.6.0",
"ps-tree": "1.2.0",
"wait-on": "3.2.0"
},
"dependencies": {
"bluebird": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
"integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==",
"dev": true
},
"execa": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.11.0.tgz",
"integrity": "sha512-k5AR22vCt1DcfeiRixW46U5tMLtBg44ssdJM9PiXw3D8Bn5qyxFCSnKY/eR22y+ctFDGPqafpaXg2G4Emyua4A==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}
}
},
"static-extend": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -12727,6 +13008,15 @@
"readable-stream": "^2.0.2"
}
},
"stream-combiner": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
"integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
"dev": true,
"requires": {
"duplexer": "~0.1.1"
}
},
"stream-each": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
@@ -13174,6 +13464,23 @@
}
}
},
"topo": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz",
"integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==",
"dev": true,
"requires": {
"hoek": "6.x.x"
},
"dependencies": {
"hoek": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz",
"integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==",
"dev": true
}
}
},
"toposort": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
@@ -13695,6 +14002,27 @@
"browser-process-hrtime": "^0.1.2"
}
},
"wait-on": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz",
"integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==",
"dev": true,
"requires": {
"core-js": "^2.5.7",
"joi": "^13.0.0",
"minimist": "^1.2.0",
"request": "^2.88.0",
"rx": "^4.1.0"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
}
},
"walker": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
@@ -14575,6 +14903,15 @@
"dev": true
}
}
},
"yauzl": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
"dev": true,
"requires": {
"fd-slicer": "~1.0.1"
}
}
}
}

View File

@@ -7,11 +7,14 @@
"scripts": {
"backend-dev": "python3.6 -m venv cellxgene && source cellxgene/bin/activate && yes | pip uninstall cellxgene || true && pip install -e .. && cellxgene launch ",
"build": "npm run clean && webpack --config configuration/webpack/webpack.config.prod.js",
"dev": "npm run clean && webpack --config configuration/webpack/webpack.config.dev.js",
"clean": "rimraf build",
"start": "node server/development.js",
"dev": "npm run clean && webpack --config configuration/webpack/webpack.config.dev.js",
"e2e": "jest e2e",
"lint": "eslint src",
"test": "jest"
"smoke-test": "start-server-and-test start-server-for-test :5000 e2e",
"start": "node server/development.js",
"start-server-for-test": "cellxgene launch -p 5000 ../example-dataset/pbmc3k.h5ad",
"unit-test": "jest --testPathIgnorePatterns e2e"
},
"engineStrict": true,
"engines": {
@@ -97,8 +100,10 @@
"jest": "^24.1.0",
"json-loader": "^0.5.4",
"mini-css-extract-plugin": "^0.4.1",
"puppeteer": "^1.12.1",
"rimraf": "^2.6.3",
"serve-favicon": "^2.3.0",
"start-server-and-test": "^1.7.11",
"style-loader": "^0.23.1",
"sw-precache-webpack-plugin": "^0.11.5",
"url-loader": "^1.1.0",

View File

@@ -237,6 +237,7 @@ class HistogramBrush extends React.Component {
d3.select(svgRef)
.append("g")
.attr("class", "brush")
.attr("data-testid", `${svgRef.id}-brush`)
.call(
d3
.brushX()
@@ -281,6 +282,8 @@ class HistogramBrush extends React.Component {
return (
<div
id={`histogram_${field}`}
data-testid={`histogram-${field}`}
data-testclass={isDiffExp ? `histogram-diffexp` : ""}
style={{
padding: globals.leftSidebarSectionPadding,
backgroundColor: zebra ? globals.lightestGrey : "white"

View File

@@ -38,6 +38,7 @@ class CellSetButton extends React.Component {
type="button"
disabled={differential.diffExp}
onClick={this.set.bind(this)}
data-testid={`cellset-button-${eitherCellSetOneOrTwo}`}
>
{eitherCellSetOneOrTwo}
{": "}

View File

@@ -68,6 +68,7 @@ class Expression extends React.Component {
style={{ marginTop: 10 }}
disabled={!haveBothCellSets}
intent="primary"
data-testid="diffexp-button"
loading={differential.loading}
fill
type="button"

View File

@@ -236,6 +236,7 @@ class GeneExpression extends React.Component {
/* this happens on 'enter' */
this.handleClick(g);
}}
inputProps={{ "data-testid": "gene-search" }}
inputValueRenderer={g => {
return "";
}}
@@ -250,6 +251,7 @@ class GeneExpression extends React.Component {
/>
<Button
className="bp3-button bp3-intent-primary"
data-testid={"add-gene"}
loading={userDefinedGenesLoading}
>
Add

View File

@@ -477,6 +477,7 @@ class Graph extends React.Component {
<canvas
width={responsive.width - this.graphPaddingRight}
height={responsive.height - this.graphPaddingTop}
data-testid="layout"
ref={canvas => {
this.reglCanvas = canvas;
}}

View File

@@ -20,6 +20,7 @@ export default (
const svg = d3
.select("#graphAttachPoint")
.append("svg")
.attr("data-testid", "layout-overlay")
.attr("width", responsive.width - graphPaddingRight)
.attr("height", responsive.height)
.attr("class", `${styles.graphSVG}`);

View File

@@ -40,6 +40,7 @@ class LeftSideBar extends React.Component {
}}
>
<p
data-testid="header"
style={{
position: "fixed",
top: globals.cellxgeneTitleTopPadding,