Merge pull request #766 from ing-bank/feat/web-test-runner
chore: use web test runner
This commit is contained in:
commit
881c20b868
16 changed files with 578 additions and 2068 deletions
|
|
@ -7,7 +7,7 @@ version: 2
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/node:10.16.0-browsers
|
- image: circleci/node:10.18.1-browsers
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
const merge = require('webpack-merge');
|
|
||||||
const bsSettings = require('@open-wc/testing-karma-bs/bs-settings.js');
|
|
||||||
const createBaseConfig = require('./karma.conf.js');
|
|
||||||
|
|
||||||
module.exports = config => {
|
|
||||||
config.set(
|
|
||||||
merge.strategy({
|
|
||||||
browsers: 'replace',
|
|
||||||
})(bsSettings(config), createBaseConfig(config), {
|
|
||||||
browserStack: {
|
|
||||||
project: 'lion',
|
|
||||||
},
|
|
||||||
browsers: [
|
|
||||||
'bs_win10_chrome_latest',
|
|
||||||
// Only chrome for now
|
|
||||||
// 'bs_win10_firefox_latest',
|
|
||||||
// 'bs_win10_edge_latest',
|
|
||||||
// 'bs_osxmojave_safari_latest',
|
|
||||||
// 'bs_win10_ie_11',
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
const { createDefaultConfig } = require('@open-wc/testing-karma');
|
|
||||||
const merge = require('webpack-merge');
|
|
||||||
|
|
||||||
module.exports = config => {
|
|
||||||
config.set(
|
|
||||||
merge(createDefaultConfig(config), {
|
|
||||||
files: [
|
|
||||||
// runs all files ending with .test in the test folder,
|
|
||||||
// can be overwritten by passing a --grep flag. examples:
|
|
||||||
//
|
|
||||||
// npm run test -- --grep test/foo/bar.test.js
|
|
||||||
// npm run test -- --grep test/bar/*
|
|
||||||
{
|
|
||||||
pattern: config.grep ? config.grep : 'packages/**/*/test/**/*.test.js',
|
|
||||||
type: 'module',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
esm: {
|
|
||||||
nodeResolve: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO: improve coverage
|
|
||||||
coverageIstanbulReporter: {
|
|
||||||
thresholds: {
|
|
||||||
global: {
|
|
||||||
statements: 80,
|
|
||||||
branches: 70,
|
|
||||||
functions: 70,
|
|
||||||
lines: 80,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
13
package.json
13
package.json
|
|
@ -22,12 +22,9 @@
|
||||||
"storybook:build": "build-storybook",
|
"storybook:build": "build-storybook",
|
||||||
"storybook:build:start": "es-dev-server --root-dir storybook-static --open",
|
"storybook:build:start": "es-dev-server --root-dir storybook-static --open",
|
||||||
"test": "run-p test:browser test:node",
|
"test": "run-p test:browser test:node",
|
||||||
"test:browser": "karma start --coverage",
|
"test:browser": "wtr packages/**/*/test/**/*.test.js --coverage",
|
||||||
"test:browser:watch": "karma start --auto-watch=true --single-run=false",
|
"test:browser:watch": "wtr packages/**/*/test/**/*.test.js --watch",
|
||||||
"test:bs": "karma start karma.bs.config.js --coverage",
|
"test:node": "lerna run test:node"
|
||||||
"test:node": "lerna run test:node",
|
|
||||||
"test:prune-snapshots": "karma start --prune-snapshots",
|
|
||||||
"test:update-snapshots": "karma start --update-snapshots"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^7.0.0",
|
"@commitlint/cli": "^7.0.0",
|
||||||
|
|
@ -38,10 +35,8 @@
|
||||||
"@open-wc/eslint-config": "^1.0.0",
|
"@open-wc/eslint-config": "^1.0.0",
|
||||||
"@open-wc/testing": "^2.5.0",
|
"@open-wc/testing": "^2.5.0",
|
||||||
"@open-wc/testing-helpers": "^1.0.0",
|
"@open-wc/testing-helpers": "^1.0.0",
|
||||||
"@open-wc/testing-karma": "^3.2.30",
|
|
||||||
"@open-wc/testing-karma-bs": "^1.3.30",
|
|
||||||
"@open-wc/testing-wallaby": "^0.1.12",
|
|
||||||
"@storybook/addon-a11y": "~5.0.0",
|
"@storybook/addon-a11y": "~5.0.0",
|
||||||
|
"@web/test-runner": "^0.2.9",
|
||||||
"@webcomponents/webcomponentsjs": "^2.2.5",
|
"@webcomponents/webcomponentsjs": "^2.2.5",
|
||||||
"babel-eslint": "^8.2.6",
|
"babel-eslint": "^8.2.6",
|
||||||
"babel-polyfill": "^6.26.0",
|
"babel-polyfill": "^6.26.0",
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lion/core": "0.7.2"
|
"@lion/core": "0.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
|
||||||
"@polymer/iron-test-helpers": "^3.0.1"
|
|
||||||
},
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"button",
|
"button",
|
||||||
"lion",
|
"lion",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from '@lion/core';
|
} from '@lion/core';
|
||||||
|
|
||||||
const isKeyboardClickEvent = e => e.keyCode === 32 /* space */ || e.keyCode === 13; /* enter */
|
const isKeyboardClickEvent = e => e.keyCode === 32 /* space */ || e.keyCode === 13; /* enter */
|
||||||
const isSpaceKeyboardClickEvent = e => e.keyCode === 32; /* space */
|
const isSpaceKeyboardClickEvent = e => e.keyCode === 32 || e.key === 32; /* space */
|
||||||
|
|
||||||
export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) {
|
export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement)) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
|
|
@ -229,8 +229,10 @@ export class LionButton extends DisabledWithTabIndexMixin(SlotMixin(LitElement))
|
||||||
const mouseupHandler = () => {
|
const mouseupHandler = () => {
|
||||||
this.active = false;
|
this.active = false;
|
||||||
document.removeEventListener('mouseup', mouseupHandler);
|
document.removeEventListener('mouseup', mouseupHandler);
|
||||||
|
this.removeEventListener('mouseup', mouseupHandler);
|
||||||
};
|
};
|
||||||
document.addEventListener('mouseup', mouseupHandler);
|
document.addEventListener('mouseup', mouseupHandler);
|
||||||
|
this.addEventListener('mouseup', mouseupHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
__keydownHandler(e) {
|
__keydownHandler(e) {
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,13 @@
|
||||||
import { browserDetection } from '@lion/core';
|
import { browserDetection } from '@lion/core';
|
||||||
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
|
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
|
||||||
import {
|
|
||||||
down,
|
|
||||||
keyDownOn,
|
|
||||||
keyUpOn,
|
|
||||||
makeMouseEvent,
|
|
||||||
pressEnter,
|
|
||||||
pressSpace,
|
|
||||||
up,
|
|
||||||
} from '@polymer/iron-test-helpers/mock-interactions.js';
|
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import '../lion-button.js';
|
import '../lion-button.js';
|
||||||
|
|
||||||
function getTopElement(el) {
|
function getClickArea(el) {
|
||||||
const { left, top, width, height } = el.getBoundingClientRect();
|
if (el.shadowRoot) {
|
||||||
// to support elementFromPoint() in polyfilled browsers we have to use document
|
return el.shadowRoot.querySelector('.click-area');
|
||||||
const crossBrowserRoot =
|
}
|
||||||
el.shadowRoot && el.shadowRoot.elementFromPoint ? el.shadowRoot : document;
|
return undefined;
|
||||||
return crossBrowserRoot.elementFromPoint(left + width / 2, top + height / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('lion-button', () => {
|
describe('lion-button', () => {
|
||||||
|
|
@ -75,14 +65,13 @@ describe('lion-button', () => {
|
||||||
describe('active', () => {
|
describe('active', () => {
|
||||||
it('updates "active" attribute on host when mousedown/mouseup on button', async () => {
|
it('updates "active" attribute on host when mousedown/mouseup on button', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
el.dispatchEvent(new Event('mousedown'));
|
||||||
|
|
||||||
down(topEl);
|
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
up(topEl);
|
el.dispatchEvent(new Event('mouseup'));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -90,14 +79,13 @@ describe('lion-button', () => {
|
||||||
|
|
||||||
it('updates "active" attribute on host when mousedown on button and mouseup anywhere else', async () => {
|
it('updates "active" attribute on host when mousedown on button and mouseup anywhere else', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
|
||||||
|
|
||||||
down(topEl);
|
el.dispatchEvent(new Event('mousedown'));
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
up(document.body);
|
document.dispatchEvent(new Event('mouseup'));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -105,14 +93,13 @@ describe('lion-button', () => {
|
||||||
|
|
||||||
it('updates "active" attribute on host when space keydown/keyup on button', async () => {
|
it('updates "active" attribute on host when space keydown/keyup on button', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
|
||||||
|
|
||||||
keyDownOn(topEl, 32);
|
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 }));
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
keyUpOn(topEl, 32);
|
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -120,14 +107,13 @@ describe('lion-button', () => {
|
||||||
|
|
||||||
it('updates "active" attribute on host when space keydown on button and space keyup anywhere else', async () => {
|
it('updates "active" attribute on host when space keydown on button and space keyup anywhere else', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
|
||||||
|
|
||||||
keyDownOn(topEl, 32);
|
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 32 }));
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
keyUpOn(document.body, 32);
|
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -135,14 +121,13 @@ describe('lion-button', () => {
|
||||||
|
|
||||||
it('updates "active" attribute on host when enter keydown/keyup on button', async () => {
|
it('updates "active" attribute on host when enter keydown/keyup on button', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
|
||||||
|
|
||||||
keyDownOn(topEl, 13);
|
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
keyUpOn(topEl, 13);
|
el.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -150,14 +135,13 @@ describe('lion-button', () => {
|
||||||
|
|
||||||
it('updates "active" attribute on host when enter keydown on button and space keyup anywhere else', async () => {
|
it('updates "active" attribute on host when enter keydown on button and space keyup anywhere else', async () => {
|
||||||
const el = await fixture(`<lion-button>foo</lion-button>`);
|
const el = await fixture(`<lion-button>foo</lion-button>`);
|
||||||
const topEl = getTopElement(el);
|
|
||||||
|
|
||||||
keyDownOn(topEl, 13);
|
el.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
|
||||||
expect(el.active).to.be.true;
|
expect(el.active).to.be.true;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.true;
|
expect(el.hasAttribute('active')).to.be.true;
|
||||||
|
|
||||||
keyUpOn(document.body, 13);
|
document.body.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
|
||||||
expect(el.active).to.be.false;
|
expect(el.active).to.be.false;
|
||||||
await el.updateComplete;
|
await el.updateComplete;
|
||||||
expect(el.hasAttribute('active')).to.be.false;
|
expect(el.hasAttribute('active')).to.be.false;
|
||||||
|
|
@ -247,7 +231,7 @@ describe('lion-button', () => {
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const button = form.querySelector('lion-button');
|
const button = form.querySelector('lion-button');
|
||||||
getTopElement(button).click();
|
getClickArea(button).click();
|
||||||
|
|
||||||
expect(formSubmitSpy.callCount).to.equal(1);
|
expect(formSubmitSpy.callCount).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
@ -260,10 +244,11 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressSpace(form.querySelector('lion-button'));
|
form
|
||||||
|
.querySelector('lion-button')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
expect(formSubmitSpy.callCount).to.equal(1);
|
expect(formSubmitSpy.callCount).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -275,7 +260,9 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressEnter(form.querySelector('lion-button'));
|
form
|
||||||
|
.querySelector('lion-button')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
|
|
@ -316,7 +303,9 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressEnter(form.querySelector('input[name="foo2"]'));
|
form
|
||||||
|
.querySelector('input[name="foo2"]')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
|
|
@ -334,7 +323,7 @@ describe('lion-button', () => {
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const button = form.querySelector('lion-button');
|
const button = form.querySelector('lion-button');
|
||||||
getTopElement(button).click();
|
getClickArea(button).click();
|
||||||
|
|
||||||
expect(formButtonClickedSpy.callCount).to.equal(1);
|
expect(formButtonClickedSpy.callCount).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
@ -347,7 +336,9 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressSpace(form.querySelector('lion-button'));
|
form
|
||||||
|
.querySelector('lion-button')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 32 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
|
|
@ -362,7 +353,9 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressEnter(form.querySelector('lion-button'));
|
form
|
||||||
|
.querySelector('lion-button')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 13 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
|
|
@ -380,7 +373,9 @@ describe('lion-button', () => {
|
||||||
</form>
|
</form>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
pressEnter(form.querySelector('input[name="foo2"]'));
|
form
|
||||||
|
.querySelector('input[name="foo2"]')
|
||||||
|
.dispatchEvent(new KeyboardEvent('keyup', { key: 13 }));
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
||||||
|
|
@ -394,7 +389,7 @@ describe('lion-button', () => {
|
||||||
const clickSpy = sinon.spy();
|
const clickSpy = sinon.spy();
|
||||||
const el = await fixture(html`<lion-button @click="${clickSpy}">foo</lion-button>`);
|
const el = await fixture(html`<lion-button @click="${clickSpy}">foo</lion-button>`);
|
||||||
|
|
||||||
getTopElement(el).click();
|
getClickArea(el).click();
|
||||||
|
|
||||||
// trying to wait for other possible redispatched events
|
// trying to wait for other possible redispatched events
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
|
|
@ -406,7 +401,11 @@ describe('lion-button', () => {
|
||||||
describe('native button behavior', async () => {
|
describe('native button behavior', async () => {
|
||||||
async function prepareClickEvent(el) {
|
async function prepareClickEvent(el) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
makeMouseEvent('click', { x: 11, y: 11 }, getTopElement(el));
|
if (getClickArea(el)) {
|
||||||
|
getClickArea(el).click();
|
||||||
|
} else {
|
||||||
|
el.click();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return oneEvent(el, 'click');
|
return oneEvent(el, 'click');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,15 @@ import { expect, fixture, html, unsafeStatic } from '@open-wc/testing';
|
||||||
import '../lion-dialog.js';
|
import '../lion-dialog.js';
|
||||||
|
|
||||||
describe('lion-dialog', () => {
|
describe('lion-dialog', () => {
|
||||||
|
// For some reason, globalRootNode is not cleared properly on disconnectedCallback from previous overlay test fixtures...
|
||||||
|
// Not sure why this "bug" happens...
|
||||||
|
beforeEach(() => {
|
||||||
|
const globalRootNode = document.querySelector('.global-overlays');
|
||||||
|
if (globalRootNode) {
|
||||||
|
globalRootNode.innerHTML = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
describe('Integration tests', () => {
|
describe('Integration tests', () => {
|
||||||
const tagString = 'lion-dialog';
|
const tagString = 'lion-dialog';
|
||||||
const tag = unsafeStatic(tagString);
|
const tag = unsafeStatic(tagString);
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,21 @@
|
||||||
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
|
import '@lion/button/lion-button';
|
||||||
|
import '@lion/checkbox-group/lion-checkbox';
|
||||||
|
import '@lion/checkbox-group/lion-checkbox-group';
|
||||||
|
import { MinLength, Required } from '@lion/form-core';
|
||||||
|
import '@lion/form/lion-form';
|
||||||
import '@lion/input-amount/lion-input-amount';
|
import '@lion/input-amount/lion-input-amount';
|
||||||
import '@lion/input-date/lion-input-date';
|
import '@lion/input-date/lion-input-date';
|
||||||
import '@lion/textarea/lion-textarea';
|
|
||||||
import '@lion/input-datepicker/lion-input-datepicker';
|
import '@lion/input-datepicker/lion-input-datepicker';
|
||||||
import '@lion/input-email/lion-input-email';
|
import '@lion/input-email/lion-input-email';
|
||||||
import '@lion/input-iban/lion-input-iban';
|
import '@lion/input-iban/lion-input-iban';
|
||||||
import '@lion/input-range/lion-input-range';
|
import '@lion/input-range/lion-input-range';
|
||||||
import '@lion/input/lion-input';
|
import '@lion/input/lion-input';
|
||||||
import '@lion/checkbox-group/lion-checkbox-group';
|
|
||||||
import '@lion/checkbox-group/lion-checkbox';
|
|
||||||
import '@lion/radio-group/lion-radio-group';
|
|
||||||
import '@lion/radio-group/lion-radio';
|
import '@lion/radio-group/lion-radio';
|
||||||
|
import '@lion/radio-group/lion-radio-group';
|
||||||
import '@lion/select/lion-select';
|
import '@lion/select/lion-select';
|
||||||
import '@lion/switch/lion-switch';
|
import '@lion/switch/lion-switch';
|
||||||
import '@lion/form/lion-form';
|
import '@lion/textarea/lion-textarea';
|
||||||
import '@lion/button/lion-button';
|
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
|
||||||
import { Required, MinLength } from '@lion/form-core';
|
|
||||||
|
|
||||||
describe(`Submitting/Resetting Form`, async () => {
|
describe(`Submitting/Resetting Form`, async () => {
|
||||||
let el;
|
let el;
|
||||||
|
|
@ -127,8 +126,6 @@ describe(`Submitting/Resetting Form`, async () => {
|
||||||
el.querySelector('#submit_button').click();
|
el.querySelector('#submit_button').click();
|
||||||
await elementUpdated(el);
|
await elementUpdated(el);
|
||||||
el.formElements.forEach(field => {
|
el.formElements.forEach(field => {
|
||||||
console.log(field);
|
|
||||||
console.log(field.submitted);
|
|
||||||
expect(field.submitted).to.be.true;
|
expect(field.submitted).to.be.true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ export class LionInputDatepicker extends ScopedElementsMixin(OverlayMixin(LionIn
|
||||||
}
|
}
|
||||||
|
|
||||||
get _calendarNode() {
|
get _calendarNode() {
|
||||||
return this._overlayCtrl.contentNode.querySelector('#calendar');
|
return this._overlayCtrl.contentNode.querySelector('[slot="content"]');
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
@ -243,7 +243,6 @@ export class LionInputDatepicker extends ScopedElementsMixin(OverlayMixin(LionIn
|
||||||
return html`
|
return html`
|
||||||
<lion-calendar
|
<lion-calendar
|
||||||
slot="content"
|
slot="content"
|
||||||
id="calendar"
|
|
||||||
.selectedDate="${this.constructor.__getSyncDownValue(this.modelValue)}"
|
.selectedDate="${this.constructor.__getSyncDownValue(this.modelValue)}"
|
||||||
.minDate="${this.__calendarMinDate}"
|
.minDate="${this.__calendarMinDate}"
|
||||||
.maxDate="${this.__calendarMaxDate}"
|
.maxDate="${this.__calendarMaxDate}"
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export class DatepickerInputObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
get calendarEl() {
|
get calendarEl() {
|
||||||
return this.overlayEl && this.overlayEl.querySelector('#calendar');
|
return this.el && this.el._calendarNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { expect } from '@open-wc/testing';
|
import { expect } from '@open-wc/testing';
|
||||||
import { localize } from '../../src/localize.js';
|
import { localize } from '../../src/localize.js';
|
||||||
import { localizeTearDown } from '../../test-helpers.js';
|
|
||||||
|
|
||||||
import { formatNumber } from '../../src/number/formatNumber.js';
|
import { formatNumber } from '../../src/number/formatNumber.js';
|
||||||
|
import { localizeTearDown } from '../../test-helpers.js';
|
||||||
|
|
||||||
const currencyCode = currency => ({ style: 'currency', currencyDisplay: 'code', currency });
|
const currencyCode = currency => ({ style: 'currency', currencyDisplay: 'code', currency });
|
||||||
const currencySymbol = currency => ({ style: 'currency', currencyDisplay: 'symbol', currency });
|
const currencySymbol = currency => ({ style: 'currency', currencyDisplay: 'symbol', currency });
|
||||||
|
|
@ -310,15 +309,17 @@ describe('formatNumber', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('tr-TR', () => {
|
describe('tr-TR', () => {
|
||||||
localize.locale = 'tr-TR';
|
it('supports basics', () => {
|
||||||
expect(formatNumber(123456.789, currencyCode('EUR'))).to.equal('123.456,79 EUR');
|
localize.locale = 'tr-TR';
|
||||||
expect(formatNumber(123456.789, currencyCode('USD'))).to.equal('123.456,79 USD');
|
expect(formatNumber(123456.789, currencyCode('EUR'))).to.equal('123.456,79 EUR');
|
||||||
expect(formatNumber(123456.789, currencyCode('JPY'))).to.equal('123.457 JPY');
|
expect(formatNumber(123456.789, currencyCode('USD'))).to.equal('123.456,79 USD');
|
||||||
expect(formatNumber(123456.789, currencyCode('TRY'))).to.equal('123.456,79 TL');
|
expect(formatNumber(123456.789, currencyCode('JPY'))).to.equal('123.457 JPY');
|
||||||
expect(formatNumber(123456.789, currencySymbol('EUR'))).to.equal('€123.456,79');
|
expect(formatNumber(123456.789, currencyCode('TRY'))).to.equal('123.456,79 TL');
|
||||||
expect(formatNumber(123456.789, currencySymbol('USD'))).to.equal('$123.456,79');
|
expect(formatNumber(123456.789, currencySymbol('EUR'))).to.equal('€123.456,79');
|
||||||
expect(formatNumber(123456.789, currencySymbol('JPY'))).to.equal('¥123.457');
|
expect(formatNumber(123456.789, currencySymbol('USD'))).to.equal('$123.456,79');
|
||||||
expect(formatNumber(123456.789, currencySymbol('TRY'))).to.equal('₺123.456,79');
|
expect(formatNumber(123456.789, currencySymbol('JPY'))).to.equal('¥123.457');
|
||||||
|
expect(formatNumber(123456.789, currencySymbol('TRY'))).to.equal('₺123.456,79');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,24 @@ function getGlobalOverlayNodes() {
|
||||||
|
|
||||||
export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
describe(`OverlayMixin${suffix}`, () => {
|
describe(`OverlayMixin${suffix}`, () => {
|
||||||
let el;
|
it('should not be opened by default', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
beforeEach(async () => {
|
|
||||||
el = await fixture(html`
|
|
||||||
<${tag}>
|
<${tag}>
|
||||||
<div slot="content">content of the overlay</div>
|
<div slot="content">content of the overlay</div>
|
||||||
<button slot="invoker">invoker button</button>
|
<button slot="invoker">invoker button</button>
|
||||||
</${tag}>
|
</${tag}>
|
||||||
`);
|
`);
|
||||||
});
|
|
||||||
|
|
||||||
it('should not be opened by default', async () => {
|
|
||||||
expect(el.opened).to.be.false;
|
expect(el.opened).to.be.false;
|
||||||
expect(el._overlayCtrl.isShown).to.be.false;
|
expect(el._overlayCtrl.isShown).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('syncs opened to overlayController', async () => {
|
it('syncs opened to overlayController', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<${tag}>
|
||||||
|
<div slot="content">content of the overlay</div>
|
||||||
|
<button slot="invoker">invoker button</button>
|
||||||
|
</${tag}>
|
||||||
|
`);
|
||||||
el.opened = true;
|
el.opened = true;
|
||||||
expect(el.opened).to.be.true;
|
expect(el.opened).to.be.true;
|
||||||
await nextFrame(); // overlayCtrl show/hide is async
|
await nextFrame(); // overlayCtrl show/hide is async
|
||||||
|
|
@ -39,6 +40,12 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('syncs OverlayController to opened', async () => {
|
it('syncs OverlayController to opened', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<${tag}>
|
||||||
|
<div slot="content">content of the overlay</div>
|
||||||
|
<button slot="invoker">invoker button</button>
|
||||||
|
</${tag}>
|
||||||
|
`);
|
||||||
expect(el.opened).to.be.false;
|
expect(el.opened).to.be.false;
|
||||||
await el._overlayCtrl.show();
|
await el._overlayCtrl.show();
|
||||||
expect(el.opened).to.be.true;
|
expect(el.opened).to.be.true;
|
||||||
|
|
@ -86,7 +93,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
|
|
||||||
it('fires "opened-changed" event on hide', async () => {
|
it('fires "opened-changed" event on hide', async () => {
|
||||||
const spy = sinon.spy();
|
const spy = sinon.spy();
|
||||||
el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} @opened-changed="${spy}">
|
<${tag} @opened-changed="${spy}">
|
||||||
<div slot="content">content of the overlay</div>
|
<div slot="content">content of the overlay</div>
|
||||||
<button slot="invoker">invoker button</button>
|
<button slot="invoker">invoker button</button>
|
||||||
|
|
@ -105,7 +112,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
|
|
||||||
it('fires "before-closed" event on hide', async () => {
|
it('fires "before-closed" event on hide', async () => {
|
||||||
const beforeSpy = sinon.spy();
|
const beforeSpy = sinon.spy();
|
||||||
el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} @before-closed="${beforeSpy}" .opened="${true}">
|
<${tag} @before-closed="${beforeSpy}" .opened="${true}">
|
||||||
<div slot="content">content of the overlay</div>
|
<div slot="content">content of the overlay</div>
|
||||||
<button slot="invoker">invoker button</button>
|
<button slot="invoker">invoker button</button>
|
||||||
|
|
@ -121,7 +128,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
|
|
||||||
it('fires before-opened" event on show', async () => {
|
it('fires before-opened" event on show', async () => {
|
||||||
const beforeSpy = sinon.spy();
|
const beforeSpy = sinon.spy();
|
||||||
el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} @before-opened="${beforeSpy}">
|
<${tag} @before-opened="${beforeSpy}">
|
||||||
<div slot="content">content of the overlay</div>
|
<div slot="content">content of the overlay</div>
|
||||||
<button slot="invoker">invoker button</button>
|
<button slot="invoker">invoker button</button>
|
||||||
|
|
@ -137,7 +144,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
function preventer(ev) {
|
function preventer(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} @before-opened="${preventer}" @before-closed="${preventer}">
|
<${tag} @before-opened="${preventer}" @before-closed="${preventer}">
|
||||||
<div slot="content">content of the overlay</div>
|
<div slot="content">content of the overlay</div>
|
||||||
<button slot="invoker">invoker button</button>
|
<button slot="invoker">invoker button</button>
|
||||||
|
|
@ -164,7 +171,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
</button>
|
</button>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} opened>
|
<${tag} opened>
|
||||||
<div slot="content">
|
<div slot="content">
|
||||||
content of the overlay
|
content of the overlay
|
||||||
|
|
@ -179,6 +186,15 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(`OverlayMixin${suffix} nested`, () => {
|
describe(`OverlayMixin${suffix} nested`, () => {
|
||||||
|
// For some reason, globalRootNode is not cleared properly on disconnectedCallback from previous overlay test fixtures...
|
||||||
|
// Not sure why this "bug" happens...
|
||||||
|
beforeEach(() => {
|
||||||
|
const globalRootNode = document.querySelector('.global-overlays');
|
||||||
|
if (globalRootNode) {
|
||||||
|
globalRootNode.innerHTML = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('supports nested overlays', async () => {
|
it('supports nested overlays', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag}>
|
<${tag}>
|
||||||
|
|
@ -216,7 +232,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const mainEl = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} id="main">
|
<${tag} id="main">
|
||||||
<div slot="content" id="mainContent">
|
<div slot="content" id="mainContent">
|
||||||
open nested overlay:
|
open nested overlay:
|
||||||
|
|
@ -226,7 +242,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
</${tag}>
|
</${tag}>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
if (mainEl._overlayCtrl.placementMode === 'global') {
|
if (el._overlayCtrl.placementMode === 'global') {
|
||||||
// Specifically checking the output in global root node, because the _contentOverlayNode still references
|
// Specifically checking the output in global root node, because the _contentOverlayNode still references
|
||||||
// the node that was removed in the teardown but hasn't been garbage collected due to reference to it still existing..
|
// the node that was removed in the teardown but hasn't been garbage collected due to reference to it still existing..
|
||||||
|
|
||||||
|
|
@ -240,7 +256,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
);
|
);
|
||||||
expect(lastContentNodeInContainer.firstElementChild.slot).to.equal('content');
|
expect(lastContentNodeInContainer.firstElementChild.slot).to.equal('content');
|
||||||
} else {
|
} else {
|
||||||
const contentNode = mainEl._overlayContentNode.querySelector('#nestedContent');
|
const contentNode = el._overlayContentNode.querySelector('#nestedContent');
|
||||||
expect(contentNode).to.not.be.null;
|
expect(contentNode).to.not.be.null;
|
||||||
expect(contentNode.innerText).to.equal('content of the nested overlay');
|
expect(contentNode.innerText).to.equal('content of the nested overlay');
|
||||||
}
|
}
|
||||||
|
|
@ -257,7 +273,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
const setupOverlayCtrlSpy = sinon.spy(nestedEl, '_setupOverlayCtrl');
|
const setupOverlayCtrlSpy = sinon.spy(nestedEl, '_setupOverlayCtrl');
|
||||||
const teardownOverlayCtrlSpy = sinon.spy(nestedEl, '_teardownOverlayCtrl');
|
const teardownOverlayCtrlSpy = sinon.spy(nestedEl, '_teardownOverlayCtrl');
|
||||||
|
|
||||||
const mainEl = await fixture(html`
|
const el = await fixture(html`
|
||||||
<${tag} id="main">
|
<${tag} id="main">
|
||||||
<div slot="content" id="mainContent">
|
<div slot="content" id="mainContent">
|
||||||
open nested overlay:
|
open nested overlay:
|
||||||
|
|
@ -279,7 +295,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) {
|
||||||
// And we detect this time the disconnect was 'permanent'
|
// And we detect this time the disconnect was 'permanent'
|
||||||
expect(teardownOverlayCtrlSpy.callCount).to.equal(1);
|
expect(teardownOverlayCtrlSpy.callCount).to.equal(1);
|
||||||
|
|
||||||
mainEl._overlayContentNode.appendChild(nestedEl);
|
el._overlayContentNode.appendChild(nestedEl);
|
||||||
await aTimeout();
|
await aTimeout();
|
||||||
expect(setupOverlayCtrlSpy.callCount).to.equal(1);
|
expect(setupOverlayCtrlSpy.callCount).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
42
wallaby.js
42
wallaby.js
|
|
@ -1,42 +0,0 @@
|
||||||
const wallabyWebpack = require('wallaby-webpack'); // eslint-disable-line import/no-extraneous-dependencies
|
|
||||||
|
|
||||||
// filter packages, e.g. 'core' / '{radio,radio-button}' / '{form,input*}'
|
|
||||||
const packagePattern = '*';
|
|
||||||
|
|
||||||
const replaceAll = (str, oldValue, newValue) => str.split(oldValue).join(newValue);
|
|
||||||
|
|
||||||
const countOccurences = (str, subbstr) => str.split(subbstr).length - 1;
|
|
||||||
|
|
||||||
const makeLionImportsRelative = file => {
|
|
||||||
// example:
|
|
||||||
// file.path: 'packages/package-name/src/my-element.js'
|
|
||||||
// old imports: '@lion/package-name'
|
|
||||||
// new imports: '../../package-name'
|
|
||||||
const nestLevel = countOccurences(file.path, '/') - 1; // 3 - 1 = 2
|
|
||||||
return replaceAll(file.content, '@lion/', '../'.repeat(nestLevel)); // '@lion/' => '../../'
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = () => ({
|
|
||||||
files: [
|
|
||||||
{ pattern: `packages/${packagePattern}/*.js`, load: false },
|
|
||||||
{ pattern: `packages/${packagePattern}/{src,translations,test}/**/*.js`, load: false },
|
|
||||||
{ pattern: `packages/${packagePattern}/test/**/*.test.js`, ignore: true },
|
|
||||||
],
|
|
||||||
filesWithNoCoverageCalculated: [
|
|
||||||
`packages/${packagePattern}/*.js`,
|
|
||||||
`packages/${packagePattern}/test/**/*.js`,
|
|
||||||
],
|
|
||||||
tests: [{ pattern: `packages/${packagePattern}/test/**/*.test.js`, load: false }],
|
|
||||||
testFramework: 'mocha',
|
|
||||||
env: {
|
|
||||||
kind: 'chrome',
|
|
||||||
},
|
|
||||||
preprocessors: {
|
|
||||||
'**/*.js': makeLionImportsRelative,
|
|
||||||
},
|
|
||||||
postprocessor: wallabyWebpack(),
|
|
||||||
setup: () => {
|
|
||||||
// required to trigger test loading
|
|
||||||
window.__moduleBundler.loadTests();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
12
web-test-runner.config.mjs
Normal file
12
web-test-runner.config.mjs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
export default {
|
||||||
|
coverage: process.argv.includes('--coverage')
|
||||||
|
? {
|
||||||
|
thresholds: {
|
||||||
|
statements: 80,
|
||||||
|
branches: 70,
|
||||||
|
functions: 70,
|
||||||
|
lines: 80,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue