aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintignore1
-rw-r--r--cypress.json4
-rw-r--r--cypress/integration/frontend-testing.js15
-rw-r--r--cypress/plugins/index.js22
-rw-r--r--cypress/support/commands.js25
-rw-r--r--cypress/support/index.js20
-rw-r--r--package.json2
-rw-r--r--static/frontend-testing.interfaces.ts10
-rw-r--r--static/frontend-testing.ts30
-rw-r--r--static/global.ts2
-rw-r--r--static/main.js1
-rw-r--r--static/tests/_all.js2
-rw-r--r--static/tests/hello-world.ts13
13 files changed, 147 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/cypress.json b/cypress.json
new file mode 100644
index 000000000..51e4c3c94
--- /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..0c1d060f7
--- /dev/null
+++ b/cypress/integration/frontend-testing.js
@@ -0,0 +1,15 @@
+function runFrontendTest(name) {
+ it(name, () => {
+ cy.window().then((win) => {
+ return win.frontendTesting.run(name);
+ });
+ });
+}
+
+describe('Frontendtestresults', () => {
+ before(() => {
+ cy.visit('/');
+ });
+
+ runFrontendTest('HelloWorld');
+});
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 000000000..59b2bab6e
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,22 @@
+/// <reference types="cypress" />
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+/**
+ * @type {Cypress.PluginConfig}
+ */
+// eslint-disable-next-line no-unused-vars
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+}
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 000000000..119ab03f7
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
diff --git a/cypress/support/index.js b/cypress/support/index.js
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/cypress/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/package.json b/package.json
index 95187ec2b..fd1a056d4 100644
--- a/package.json
+++ b/package.json
@@ -104,6 +104,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",
@@ -155,6 +156,7 @@
"test": "mocha --recursive",
"check": "npm run lint && npm run test",
"dev": "cross-env NODE_ENV=DEV node -r esm -r ts-node/register app.js",
+ "frontend-test": "cross-env NODE_ENV=DEV node -r esm -r ts-node/register app.js --frontendTesting true",
"debugger": "cross-env NODE_ENV=DEV node --inspect -r esm -r ts-node/register app.js --debug",
"debug": "cross-env NODE_ENV=DEV node -r esm -r ts-node/register app.js --debug",
"start": "webpack && cross-env NODE_ENV=LOCAL node -r esm -r ts-node/register app.js",
diff --git a/static/frontend-testing.interfaces.ts b/static/frontend-testing.interfaces.ts
new file mode 100644
index 000000000..1666b2a51
--- /dev/null
+++ b/static/frontend-testing.interfaces.ts
@@ -0,0 +1,10 @@
+
+export interface ICETestable {
+ readonly description: string;
+ run(): Promise<void>;
+};
+
+export interface ICEFrontendTesting {
+ add(test: ICETestable);
+ run(testToRun: string): Promise<void>;
+}
diff --git a/static/frontend-testing.ts b/static/frontend-testing.ts
new file mode 100644
index 000000000..f11061957
--- /dev/null
+++ b/static/frontend-testing.ts
@@ -0,0 +1,30 @@
+import { ICEFrontendTesting, ICETestable } from './frontend-testing.interfaces';
+
+class CEFrontendTesting implements ICEFrontendTesting {
+ private testSuites: Array<ICETestable>;
+
+ constructor() {
+ this.testSuites = [];
+ }
+
+ public add(test: ICETestable) {
+ this.testSuites.push(test);
+ }
+
+ 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.frontendTesting = new CEFrontendTesting();
diff --git a/static/global.ts b/static/global.ts
index cf242be89..7342cf618 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 { ICEFrontendTesting } from './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;
+ frontendTesting: ICEFrontendTesting;
ga: any;
GoogleAnalyticsObject: any;
}
diff --git a/static/main.js b/static/main.js
index 593e1a756..e1168b405 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..696378525
--- /dev/null
+++ b/static/tests/_all.js
@@ -0,0 +1,2 @@
+require('../frontend-testing');
+require('./hello-world');
diff --git a/static/tests/hello-world.ts b/static/tests/hello-world.ts
new file mode 100644
index 000000000..08b137cdd
--- /dev/null
+++ b/static/tests/hello-world.ts
@@ -0,0 +1,13 @@
+import { ICETestable } from "../frontend-testing.interfaces";
+import { assert } from 'chai';
+
+class HelloWorldTests implements ICETestable {
+ public readonly description: string = 'HelloWorld';
+
+ public async run() {
+ const person = true;
+ assert.equal(person, true);
+ }
+}
+
+window.frontendTesting.add(new HelloWorldTests());