mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 09:42:02 +08:00
Add smoke test script that runs in chrome headless.
This commit is contained in:
parent
b9f553d45d
commit
8d44642b97
|
@ -31,7 +31,15 @@ task "smoke:test" do
|
|||
end
|
||||
|
||||
results = ""
|
||||
IO.popen("#{phantom_path} #{Rails.root}/spec/phantom_js/smoke_test.js #{url}").each do |line|
|
||||
|
||||
command =
|
||||
if ENV["USE_CHROME"]
|
||||
"node #{Rails.root}/test/smoke_test.js #{url}"
|
||||
else
|
||||
"#{phantom_path} #{Rails.root}/spec/phantom_js/smoke_test.js #{url}"
|
||||
end
|
||||
|
||||
IO.popen(command).each do |line|
|
||||
puts line
|
||||
results << line
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"chrome-launcher": "^0.10.0",
|
||||
"chrome-remote-interface": "^0.25.4"
|
||||
"chrome-remote-interface": "^0.25.4",
|
||||
"puppeteer": "^0.13.0"
|
||||
}
|
||||
}
|
||||
|
|
235
test/smoke_test.js
Normal file
235
test/smoke_test.js
Normal file
|
@ -0,0 +1,235 @@
|
|||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length < 1 || args.length > 2) {
|
||||
console.log("Expecting: node {smoke_test.js} {url}");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const url = args[0];
|
||||
|
||||
console.log(`Starting Discourse Smoke Test for ${url}`);
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
const path = require('path');
|
||||
|
||||
(async () => {
|
||||
const browser = await puppeteer.launch({
|
||||
// headless: false,
|
||||
// slowMo: 10,
|
||||
args: ["--disable-local-storage"]
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
|
||||
page.setViewport = {
|
||||
width: 1366,
|
||||
height: 768
|
||||
};
|
||||
|
||||
const exec = (description, fn, assertion) => {
|
||||
const start = +new Date();
|
||||
|
||||
return fn.call().then(output => {
|
||||
if (assertion) {
|
||||
if (assertion.call(this, output)) {
|
||||
console.log(`PASSED: ${description} - ${(+new Date()) - start}ms`);
|
||||
} else {
|
||||
console.log(`FAILED: ${description} - ${(+new Date()) - start}ms`);
|
||||
console.log("SMOKE TEST FAILED");
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
console.log(`PASSED: ${description} - ${(+new Date()) - start}ms`);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(`ERROR (${description}): ${error.message} - ${(+new Date()) - start}ms`);
|
||||
console.log("SMOKE TEST FAILED");
|
||||
process.exit(1);
|
||||
});
|
||||
};
|
||||
|
||||
const assert = (description, fn, assertion) => {
|
||||
return exec(description, fn, assertion);
|
||||
};
|
||||
|
||||
page.on('console', msg => console.log(`PAGE LOG: ${msg.text}`));
|
||||
|
||||
await page.goto(url);
|
||||
|
||||
await exec("expect a log in button in the header", () => {
|
||||
return page.waitForSelector("header .login-button", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("go to latest page", () => {
|
||||
return page.goto(path.join(url, 'latest'), { timeout: 1500 });
|
||||
});
|
||||
|
||||
await exec("at least one topic shows up", () => {
|
||||
return page.waitForSelector(".topic-list tbody tr", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("go to categories page", () => {
|
||||
return page.goto(path.join(url, 'categories'), { timeout: 1500 });
|
||||
});
|
||||
|
||||
await exec("can see categories on the page", () => {
|
||||
return page.waitForSelector(".category-list", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("navigate to 1st topic", () => {
|
||||
return page.click(".main-link a.title:first-of-type", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("at least one post body", () => {
|
||||
return page.waitForSelector(".topic-post", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("click on the 1st user", () => {
|
||||
return page.click(".topic-meta-data a:first-of-type", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("user has details", () => {
|
||||
return page.waitForSelector("#user-card .names", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
if (!process.env.READONLY_TESTS) {
|
||||
await exec("open login modal", () => {
|
||||
return page.click(".login-button", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("login modal is open", () => {
|
||||
return page.waitForSelector(".login-modal", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("type in credentials & log in", () => {
|
||||
let promise = page.type("#login-account-name", process.env.DISCOURSE_USERNAME || 'smoke_user');
|
||||
|
||||
promise = promise.then(() => {
|
||||
return page.type("#login-account-password", process.env.DISCOURSE_PASSWORD || 'P4ssw0rd');
|
||||
});
|
||||
|
||||
promise = promise.then(() => {
|
||||
return page.click(".login-modal .btn-primary", { timeout: 500 });
|
||||
});
|
||||
|
||||
return promise;
|
||||
});
|
||||
|
||||
await exec("is logged in", () => {
|
||||
return page.waitForSelector(".current-user", { timeout: 2000, visible: true });
|
||||
});
|
||||
|
||||
await exec("go home", () => {
|
||||
return page.click("#site-logo, #site-text-logo", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("it shows a topic list", () => {
|
||||
return page.waitForSelector(".topic-list", { timeout: 1500, visible: true });
|
||||
});
|
||||
|
||||
await exec("we have a create topic button", () => {
|
||||
return page.waitForSelector("#create-topic", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("open composer", () => {
|
||||
return page.click("#create-topic", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("the editor is visible", () => {
|
||||
return page.waitForFunction(
|
||||
"document.activeElement === document.getElementById('reply-title')",
|
||||
{ timeout: 500 }
|
||||
);
|
||||
});
|
||||
|
||||
await exec("compose new topic", () => {
|
||||
const date = `(${(+new Date())})`;
|
||||
const title = `This is a new topic ${date}`;
|
||||
const post = `I can write a new topic inside the smoke test! ${date} \n\n`;
|
||||
|
||||
let promise = page.type("#reply-title", title);
|
||||
|
||||
promise = promise.then(() => {
|
||||
return page.type("#reply-control .d-editor-input", post);
|
||||
});
|
||||
|
||||
return promise;
|
||||
});
|
||||
|
||||
await exec("updates preview", () => {
|
||||
return page.waitForSelector(".d-editor-preview p", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("open upload modal", () => {
|
||||
return page.click(".d-editor-button-bar .upload", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("upload modal is open", () => {
|
||||
let promise = page.waitForSelector("#filename-input", { timeout: 1500, visible: true });
|
||||
|
||||
promise.then(() => {
|
||||
return page.click(".d-modal-cancel", { timeout: 500 });
|
||||
});
|
||||
|
||||
return promise;
|
||||
});
|
||||
|
||||
await exec("submit the topic", () => {
|
||||
return page.click(".submit-panel .create", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("topic is created", () => {
|
||||
return page.waitForSelector(".fancy-title", { timeout: 1500, visible: true });
|
||||
});
|
||||
|
||||
await exec("open the composer", () => {
|
||||
return page.click(".post-controls:first-of-type .create", { timeout: 500 });
|
||||
});
|
||||
|
||||
await exec("composer is open", () => {
|
||||
return page.waitForSelector("#reply-control .d-editor-input", { timeout: 500, visible: true });
|
||||
});
|
||||
|
||||
await exec("compose reply", () => {
|
||||
const post = `I can even write a reply inside the smoke test ;) (${(+new Date())})`;
|
||||
return page.type("#reply-control .d-editor-input", post);
|
||||
});
|
||||
|
||||
await assert("waiting for the preview", () => {
|
||||
let promise = page.waitForSelector(".d-editor-preview p",
|
||||
{ timeout: 500, visible: true }
|
||||
);
|
||||
|
||||
promise = promise.then(() => {
|
||||
return page.evaluate(() => {
|
||||
return document.querySelector(".d-editor-preview").innerText;
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, output => {
|
||||
return output.match("I can even write a reply");
|
||||
});
|
||||
|
||||
await exec("submit the topic", () => {
|
||||
return page.click("#reply-control .create", { timeout: 6000 });
|
||||
});
|
||||
|
||||
await assert("reply is created", () => {
|
||||
let promise = page.waitForSelector(".topic-post", { timeout: 500 });
|
||||
|
||||
promise = promise.then(() => {
|
||||
return page.evaluate(() => {
|
||||
return document.querySelectorAll(".topic-post").length;
|
||||
});
|
||||
});
|
||||
|
||||
return promise;
|
||||
}, output => {
|
||||
return output === 2;
|
||||
});
|
||||
}
|
||||
|
||||
await browser.close();
|
||||
|
||||
console.log("ALL PASSED");
|
||||
})();
|
139
yarn.lock
139
yarn.lock
|
@ -18,6 +18,12 @@
|
|||
version "0.0.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-0.0.28.tgz#5562519bc7963caca8abf7f128cae3b594d41d06"
|
||||
|
||||
agent-base@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.1.2.tgz#80fa6cde440f4dcf9af2617cf246099b5d99f0c8"
|
||||
dependencies:
|
||||
es6-promisify "^5.0.0"
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
|
@ -61,12 +67,55 @@ concat-map@0.0.1:
|
|||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
debug@^2.6.8:
|
||||
concat-stream@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
||||
debug@2.6.9, debug@^2.6.8:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
|
||||
|
||||
es6-promisify@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
extract-zip@^1.6.5:
|
||||
version "1.6.6"
|
||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c"
|
||||
dependencies:
|
||||
concat-stream "1.6.0"
|
||||
debug "2.6.9"
|
||||
mkdirp "0.5.0"
|
||||
yauzl "2.4.1"
|
||||
|
||||
fd-slicer@~1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
@ -82,6 +131,13 @@ glob@^7.0.5:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
https-proxy-agent@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
|
||||
dependencies:
|
||||
agent-base "^4.1.0"
|
||||
debug "^3.1.0"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
|
@ -89,7 +145,7 @@ inflight@^1.0.4:
|
|||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
|
@ -97,12 +153,20 @@ is-wsl@^1.1.0:
|
|||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
|
||||
|
||||
isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
lighthouse-logger@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lighthouse-logger/-/lighthouse-logger-1.0.1.tgz#f073d83f7acbc96729bf100a121c8f006991ae61"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
|
||||
mime@^1.3.4:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
|
@ -113,6 +177,12 @@ minimist@0.0.8:
|
|||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
|
||||
mkdirp@0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
mkdirp@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
|
@ -133,28 +203,89 @@ path-is-absolute@^1.0.0:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
|
||||
progress@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
|
||||
|
||||
proxy-from-env@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
|
||||
|
||||
puppeteer@^0.13.0:
|
||||
version "0.13.0"
|
||||
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-0.13.0.tgz#2e6956205f2c640964c2107f620ae1eef8bde8fd"
|
||||
dependencies:
|
||||
debug "^2.6.8"
|
||||
extract-zip "^1.6.5"
|
||||
https-proxy-agent "^2.1.0"
|
||||
mime "^1.3.4"
|
||||
progress "^2.0.0"
|
||||
proxy-from-env "^1.0.0"
|
||||
rimraf "^2.6.1"
|
||||
ws "^3.0.0"
|
||||
|
||||
readable-stream@^2.2.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~1.0.6"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.0.3"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
rimraf@^2.6.1:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
safe-buffer@~5.1.0:
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
|
||||
|
||||
string_decoder@~1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
||||
ws@3.3.x:
|
||||
ws@3.3.x, ws@^3.0.0:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.2.tgz#96c1d08b3fefda1d5c1e33700d3bfaa9be2d5608"
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
safe-buffer "~5.1.0"
|
||||
ultron "~1.1.0"
|
||||
|
||||
yauzl@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"
|
||||
dependencies:
|
||||
fd-slicer "~1.0.1"
|
||||
|
|
Loading…
Reference in New Issue
Block a user