UNPKG

reportage

Version:

Scenarist-wrapped mocha sessions on browsers to any reporters

336 lines (333 loc) 12.3 kB
/* @license https://github.com/t2ym/reportage/blob/master/LICENSE.md Copyright (c) 2023 Tetsuya Mori <t2y3141592@gmail.com>. All rights reserved. */ import { default as Suite, Config, chai, assert } from "./common-suite.js"; /* const console = { log() { globalThis.console.log(...arguments); let log = localStorage.getItem('console.log'); if (!log) { log = []; } else { log = JSON.parse(log); } log.push([...arguments]); localStorage.setItem('console.log', JSON.stringify(log, null, 2)); } } */ // example scope let scope = 'example'; let example = new Suite(scope, 'Description of Example Suite'); example.htmlSuite = '/test/mocha.html'; let CommonSuite; example.test = CommonSuite = Suite.scopes.common.classes.CommonSuite; // test class mixin in "example" scope example.test = (base) => class TestA extends base { get description() { return 'Description of Test A'; } * iteration() { yield * [ { name: 'Test A it 0' }, { name: 'Test A it 1' } ]; } async operation(parameters, _this) { this.skipPhase(_this); console.log(parameters.name); //console.log(`Test A suiteParameters: ${JSON.stringify(this.target)}`); //this.element = document.querySelector('#example') } async checkpoint(parameters) { console.log('Checkpoint for Test A'); //assert.equal(this.element.is, 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test A'); } } example.test = (base) => class TestB extends base { get description() { return 'Description of Test B'; } static get reconnectable() { return false; } async operation(_this) { this.stepPhase(); if (this.currentPhase + 1 === this.phase) { console.log('Test B operation (deferred navigation)', this.phase, this.currentPhase); Object.assign(this.target, { phase: this.phase, _url: (new URL(`/test/mocha2.html?x_phase=${this.phase}`, location.href)).href, deferredNavigation() { const navigate = function (url) { console.log(`TestB: history.pushState(null, '', "${url}")`); history.pushState(null, '', url); // history.length is reset as 2 if (url !== location.href) { console.log(`TestB:navigate() location.href ${location.href} !== url ${url}`); setTimeout(() => { console.log(`TestB:navigate() recalling navigate(${url}) after 1000ms`); navigate(url); }, 1000); } window.addEventListener('beforeunload', (event) => { console.log(`TestB: beforeunload`); setTimeout(() => { console.log(`TestB: recalling history.go() 100ms after beforeunload`); history.go(); }, 100); }); window.addEventListener('unload', (event) => { console.log(`TestB: unload`); }); console.log(`TestB: history.go()`, history.state, location.href, document.readyState); history.go(); } const a = document.querySelector('#_link'); a.href = this._url; a.click(); //location.assign(this._url); //navigate(this._url); }, }); } } async checkpoint(_this) { this.skipPhase(_this); console.log('Checkpoint for Test B (deferred navigation)', this.phase, this.currentPhase, history.length, location.href); assert.equal(location.href, (new URL(`/test/mocha2.html?x_phase=${this.phase}`, location.href)).href, 'Deferred navigation URL'); //assert.equal(history.length, this.phase + 1, 'history.length === this.phase + 1'); //chai.assert.isOk(false, 'Failing test B'); } } example.test = (base) => class Test1 extends base { get description() { return 'Description of Test 1'; } //static get skipAfterFailure() { return false; } async operation(_this) { this.skipPhase(_this); location.replace('#Test1'); //this.element = document.querySelector('#example') } async checkpoint(_this) { console.log('Checkpoint for Test 1'); chai.assert.equal(location.hash, '#Test1', 'URL hash is #Test1'); //chai.assert.equal(JSON.stringify(Object.keys(_this)), '', 'test context exists'); this.addContext(_this, { title: 'screenshot', value: new URL('assets/thin-hook-icon.png', new URL(Config.consoleReporterOptions.reportDir, Config.reporterOrigin)) }); //chai.assert.equal(JSON.stringify(Object.keys(_this.test)), 'object', 'typeof this.context is object'); //await new Promise(resolve => setTimeout(resolve, 5000)); //chai.assert.equal(_this.test.currentRetry(), 1, 'currentRetry is 1'); chai.assert.equal('broken-element', 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test 1'); } } example.test = (base) => class Test2 extends base { get description() { return 'Description of Test 2'; } async operation(_this) { this.skipPhase(_this); console.log('Test 2 operation'); //this.element = document.querySelector('#example') } async checkpoint() { console.log('Checkpoint for Test 2'); //chai.assert.equal('Test 2', 'must throw'); //chai.assert.throws(() => { // debugger; //}); //chai.assert.equal('fake-example-element', 'example-element', 'Element is instantiated'); //chai.assert.isOk(false, 'Failing test 2'); } } example.test = (base) => class Test3 extends base { get description() { return 'Description of Test 3'; } async operation(_this) { this.skipPhase(_this); console.log('Test 3 operation'); //this.element = document.querySelector('#example') } async checkpoint() { console.log('Checkpoint for Test 3'); //chai.assert.equal('Test 2', 'must throw'); //chai.assert.throws(() => { // debugger; //}); //chai.assert.equal('fake-example-element', 'example-element', 'Element is instantiated'); chai.assert.isOk(false, 'Failing Test 3'); } } example.test = (base) => class Test4 extends base { get description() { return 'Description of Test 4'; } async operation(_this) { this.skipPhase(_this); console.log('Test 4 operation'); //this.element = document.querySelector('#example') } async checkpoint() { console.log('Checkpoint for Test 4'); //assert.equal(history.length, this.phase + 1, 'history.length === this.phase + 1'); //chai.assert.equal('Test 2', 'must throw'); //chai.assert.throws(() => { // debugger; //}); //chai.assert.equal('fake-example-element', 'example-element', 'Element is instantiated'); //chai.assert.isOk(false, 'Failing test 2'); } } example.test = (base) => class RetryableTest1 extends base { get description() { return 'Description of RetryableTest 1'; } static get skipAfterFailure() { return false; } // must not skip the retried test even after a failure async operation(_this) { this.skipPhase(_this); // Note: Every Retryable test must come at the end of a test scenario // to avoid unexpected affects of retried tests on subsequent test scenario _this.test.retries(1); // set retries as 1 location.replace('#RetryableTest1'); //this.element = document.querySelector('#example') } async checkpoint(_this) { console.log('Checkpoint for RetryableTest 1'); chai.assert.equal(location.hash, '#RetryableTest1', 'URL hash is #RetryableTest1'); //_this.test.context = [`${Config.reporterOrigin}/mochawesome-report/assets/thin-hook-icon.png`]; //chai.assert.equal(JSON.stringify(Object.keys(_this.test)), 'object', 'typeof this.context is object'); //await new Promise(resolve => setTimeout(resolve, 5000)); chai.assert.equal(_this.test.currentRetry(), 1, 'fails at 1st attempt (currentRetry 0); succeed in the 2nd trial (currentRetry 1); currentRetry is 1'); //chai.assert.equal('broken-element', 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test 1'); } } example.test = (base) => class RetryableTest2 extends base { get description() { return 'Description of RetryableTest 2'; } static get skipAfterFailure() { return false; } // must not skip the retried test even after a failure async operation(_this) { this.skipPhase(_this); // Note: Every Retryable test must come at the end of a test scenario // to avoid unexpected affects of retried tests on subsequent test scenario _this.test.retries(3); // set retries as 3 location.replace('#RetryableTest2'); //this.element = document.querySelector('#example') } async checkpoint(_this) { console.log('Checkpoint for RetryableTest 2'); chai.assert.equal(location.hash, '#RetryableTest2', 'URL hash is #RetryableTest2'); //_this.test.context = [`${Config.reporterOrigin}/mochawesome-report/assets/thin-hook-icon.png`]; //chai.assert.equal(JSON.stringify(Object.keys(_this.test)), 'object', 'typeof this.context is object'); //await new Promise(resolve => setTimeout(resolve, 5000)); chai.assert.equal(_this.test.currentRetry(), 100, 'currentRetry is 100; always fails on all trials'); //chai.assert.equal('broken-element', 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test 1'); } } example.test = class TestC extends CommonSuite { get description() { return 'Description of Test C'; } async operation(_this) { this.skipPhase(_this); console.log('Test C operation'); //this.element = document.querySelector('#example') } async checkpoint() { console.log('Checkpoint for Test C'); //assert.equal(this.element.is, 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test A'); } } ///* example.test = class TestD extends CommonSuite { get description() { return 'Description of Test D'; } async operation(_this) { this.skipPhase(_this); console.log('Test D operation'); //this.element = document.querySelector('#example') } async checkpoint() { console.log('Checkpoint for Test D'); //assert.equal(this.element.is, 'example-element', 'Element is instantiated'); //assert.isOk(false, 'Failing test A'); } } example.test = class TestE extends CommonSuite { static get skipAfterFailure() { return true; } async operation(_this) { this.skipPhase(_this); console.log(`TestE operation`); } async checkpoint() { console.log(`TestE checkpoint`); } } // scenarios example.test = { // test class mixins '': [ { TestA: { TestB: 'TestAThenB' }, TestB: { TestA: 'TestBThenA' }, }, Suite.repeat('TestAThenB', 3, 'TestAB3') ], // test classes TestC: { TestAThenB: 'TestCAB' }, TestD: 'TestDAlias', TestE: [ { TestAThenB: 'TestEAB', TestA: { Test1: 'TestEA1', Test2: 'TestEA2', TestB: { Test1: { Test2: 'TestEAB12' } }, TestBThenA: 'TestEABA' }, TestB: { Test1: '' }, TestAB3: 'TestEAB3; Description of "Test EAB3"', // Note: Every Retryable test must come at the end of a test scenario // to avoid unexpected affects of retried tests on subsequent test scenario RetryableTest1: 'TestERetryableTest1; Description of "Test E then RetryableTest 1"', RetryableTest2: 'TestERetryableTest2; Description of "Test E then RetryableTest 2"', }, Suite.permute([ 'TestA', 'TestB', 'Test1' /* , 'Test3', 'Test2', 'Test4' */ ], (scenario) => ({ Test2: 'Test_E_' + scenario.map(n => n.replace(/^Test/,'')).join('_') + '_2' })) ] }; //*/ /* example.test = { // test class mixins '': [ { TestA: { TestB: 'TestAThenB' }, TestB: { TestA: 'TestBThenA' }, }, Suite.repeat('TestAThenB', 3, 'TestAB3') ], // test classes TestC: { TestAThenB: 'TestCAB', TestBThenA: { TestBThenA: { TestBThenA: { Test4: 'TestCBABABA4', }, }, }, }, }; */ //let match = decodeURIComponent(window.location.href).match(/^.*[^_a-zA-Z0-9]TestSuites=([_a-zA-Z0-9,]*).*$/); //if (match) { // Runner // match[1] = '0' for the first round of test suites runnable without reloading //example.run(0, '#example'); //} export default Suite;