aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Quist <partouf@gmail.com>2022-01-25 10:17:56 +0000
committerGitHub <noreply@github.com>2022-01-25 10:17:56 +0000
commitda52309abd040d67e92d9ba876175adb773e4e18 (patch)
tree7bf9f230d0887ed00646db95d2933995784b0875
parentb83dafac61c0972498b0dd8c0ea41db57d4edc81 (diff)
parent040bffa405fca17e9c24986943a7dada1f392919 (diff)
downloadcompiler-explorer-gh-1711.tar.gz
compiler-explorer-gh-1711.zip
Merge 040bffa405fca17e9c24986943a7dada1f392919 into b83dafac61c0972498b0dd8c0ea41db57d4edc81gh-1711
-rw-r--r--.eslintignore1
-rw-r--r--.github/workflows/test-frontend.yml19
-rw-r--r--cypress.json4
-rw-r--r--cypress/integration/frontend-testing.js15
-rw-r--r--docs/internal/FrontendTesting.md28
-rw-r--r--package.json1
-rw-r--r--static/global.ts2
-rw-r--r--static/main.js1
-rw-r--r--static/tests/_all.js2
-rw-r--r--static/tests/frontend-testing.interfaces.ts11
-rw-r--r--static/tests/frontend-testing.ts30
-rw-r--r--static/tests/hello-world.ts13
12 files changed, 127 insertions, 0 deletions
diff --git a/.eslintignore b/.eslintignore
index f924bb187..23e42fd24 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -5,6 +5,7 @@ etc
examples
out
views
+cypress
# Autogenerated files
lib/handlers/asm-docs-*.js
diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml
new file mode 100644
index 000000000..c2e76c0e9
--- /dev/null
+++ b/.github/workflows/test-frontend.yml
@@ -0,0 +1,19 @@
+name: Compiler Explorer Frontend Testing
+
+on: [push]
+jobs:
+ cypress-run:
+ if: github.repository_owner == 'compiler-explorer'
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Clean
+ run: make clean
+ - name: Install prerequisites
+ run: make prereqs
+ - name: Cypress run
+ uses: cypress-io/github-action@v2
+ with:
+ start: npm run dev
+ wait-on: 'http://localhost:10240'
diff --git a/cypress.json b/cypress.json
new file mode 100644
index 000000000..147681380
--- /dev/null
+++ b/cypress.json
@@ -0,0 +1,4 @@
+{
+ "baseUrl": "http://127.0.0.1:10240/",
+ "downloadsFolder": "cypress/downloads"
+} \ No newline at end of file
diff --git a/cypress/integration/frontend-testing.js b/cypress/integration/frontend-testing.js
new file mode 100644
index 000000000..4dcc06709
--- /dev/null
+++ b/cypress/integration/frontend-testing.js
@@ -0,0 +1,15 @@
+function runFrontendTest(name) {
+ it(name, () => {
+ cy.window().then((win) => {
+ return win.compilerExplorerFrontendTesting.run(name);
+ });
+ });
+}
+
+describe('Frontendtestresults', () => {
+ before(() => {
+ cy.visit('/');
+ });
+
+ runFrontendTest('HelloWorld');
+});
diff --git a/docs/internal/FrontendTesting.md b/docs/internal/FrontendTesting.md
new file mode 100644
index 000000000..1320c55a6
--- /dev/null
+++ b/docs/internal/FrontendTesting.md
@@ -0,0 +1,28 @@
+# Frontend testing
+
+We have a mixture of typescript in the main website's code (located in `static/tests`) and Cypress (located in `cypress/integration`) to test and report on the workings of that code.
+
+But there's always the possibility to use Cypress code to do UI checks and testing.
+
+## Recommended
+
+The recommended way of testing is to use typescript to test the inner workings of the various interfaces that are available.
+
+This has the advantage of having types and being able to verify your code is consistent with the rest of the website and probably going to run correctly - without having to startup the website and Cypress.
+
+## Adding a test
+
+Steps to add a test:
+
+* Create a new file in `static/tests` (copy paste from `static/tests/hello-world.ts`)
+* Make sure to change the `description` as well as the test
+* Add the file to the imports of `static/tests/_all.js`
+* Add a `runFrontendTest()` call with the new test description to `cypress/integration/frontend-testing.js`
+
+## Starting tests locally
+
+You don't need to install an entire X server to actually run cypress (just xfvb).
+
+You can find a complete list at https://docs.cypress.io/guides/getting-started/installing-cypress#System-requirements
+
+If you have the prerequisites installed, you should be able to run `npx cypress run` - however, you will need to start the CE website seperately in another terminal before that.
diff --git a/package.json b/package.json
index a21efaa10..e3ac3667f 100644
--- a/package.json
+++ b/package.json
@@ -107,6 +107,7 @@
"copy-webpack-plugin": "^9.1.0",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.3.1",
+ "cypress": "^9.2.0",
"deep-equal-in-any-order": "^1.1.15",
"eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
diff --git a/static/global.ts b/static/global.ts
index cf242be89..17c9c5bb2 100644
--- a/static/global.ts
+++ b/static/global.ts
@@ -22,6 +22,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
+import { IFrontendTesting } from './tests/frontend-testing.interfaces';
import { Options } from './options.interfaces';
type CompilerExplorerOptions = Record<string, unknown> & Options
@@ -31,6 +32,7 @@ declare global {
httpRoot: string | null;
staticRoot: string | null;
compilerExplorerOptions: CompilerExplorerOptions;
+ compilerExplorerFrontendTesting: IFrontendTesting;
ga: any;
GoogleAnalyticsObject: any;
}
diff --git a/static/main.js b/static/main.js
index 020ef62fd..1d3685a3b 100644
--- a/static/main.js
+++ b/static/main.js
@@ -51,6 +51,7 @@ var SimpleCook = require('./simplecook').SimpleCook;
var HistoryWidget = require('./history-widget').HistoryWidget;
var History = require('./history');
var presentation = require('./presentation');
+require('./tests/_all');
//css
require('bootstrap/dist/css/bootstrap.min.css');
diff --git a/static/tests/_all.js b/static/tests/_all.js
new file mode 100644
index 000000000..c48277685
--- /dev/null
+++ b/static/tests/_all.js
@@ -0,0 +1,2 @@
+require('./frontend-testing');
+require('./hello-world');
diff --git a/static/tests/frontend-testing.interfaces.ts b/static/tests/frontend-testing.interfaces.ts
new file mode 100644
index 000000000..a35b02ac6
--- /dev/null
+++ b/static/tests/frontend-testing.interfaces.ts
@@ -0,0 +1,11 @@
+
+export interface ITestable {
+ readonly description: string;
+ run(): Promise<void>;
+};
+
+export interface IFrontendTesting {
+ add(test: ITestable);
+ getAllTestNames(): string[];
+ run(testToRun: string): Promise<void>;
+}
diff --git a/static/tests/frontend-testing.ts b/static/tests/frontend-testing.ts
new file mode 100644
index 000000000..97d45cf33
--- /dev/null
+++ b/static/tests/frontend-testing.ts
@@ -0,0 +1,30 @@
+import { IFrontendTesting, ITestable } from './frontend-testing.interfaces';
+
+class FrontendTesting implements IFrontendTesting {
+ private testSuites: Array<ITestable> = [];
+
+ public add(test: ITestable) {
+ this.testSuites.push(test);
+ }
+
+ public getAllTestNames(): string[] {
+ return this.testSuites.map((val) => val.description);
+ }
+
+ private findTest(name: string) {
+ for (const suite of this.testSuites) {
+ if (suite.description === name) {
+ return suite;
+ }
+ }
+
+ throw new Error(`Can't find test ${name}`);
+ }
+
+ public async run(testToRun: string) {
+ const testSuite = this.findTest(testToRun);
+ await testSuite.run();
+ }
+}
+
+window.compilerExplorerFrontendTesting = new FrontendTesting();
diff --git a/static/tests/hello-world.ts b/static/tests/hello-world.ts
new file mode 100644
index 000000000..2c05d7b02
--- /dev/null
+++ b/static/tests/hello-world.ts
@@ -0,0 +1,13 @@
+import { ITestable } from "./frontend-testing.interfaces";
+import { assert } from 'chai';
+
+class HelloWorldTests implements ITestable {
+ public readonly description: string = 'HelloWorld';
+
+ public async run() {
+ const person = true;
+ assert.equal(person, true);
+ }
+}
+
+window.compilerExplorerFrontendTesting.add(new HelloWorldTests());