Skip to content

Commit

Permalink
ISSUE-2351 Run all browser tests with and without polyfill
Browse files Browse the repository at this point in the history
remove unnecessary polyfill loading

scripts that need polyfill import themselves + unnecessary mocking removal

separate tests that require polyfill from tests that do not

remove unneeded test

web test runner create groups for tests to run with and without polyfills

refactor: rename
  • Loading branch information
aghArdeshir committed Oct 6, 2024
1 parent 4696ad7 commit 2e883d6
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 116 deletions.
40 changes: 40 additions & 0 deletions packages/ui/components/core/test/SlotMixin.polyfill.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import sinon from 'sinon';
import { defineCE, expect, fixture, unsafeStatic, html } from '@open-wc/testing';
import { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
import { SlotMixin } from '@lion/ui/core.js';
import { LitElement } from 'lit';

it('supports scoped elements when polyfill loaded', async () => {
// @ts-ignore the scoped-custom-element-registry polyfill makes sure `ShadowRoot.prototype.createElement` is defined
const createElementSpy = sinon.spy(ShadowRoot.prototype, 'createElement');

class ScopedEl extends LitElement {}

const tagName = defineCE(
class extends ScopedElementsMixin(SlotMixin(LitElement)) {
static get scopedElements() {
return {
// @ts-expect-error
...super.scopedElements,
'scoped-elm': ScopedEl,
};
}

get slots() {
return {
...super.slots,
template: () => html`<scoped-elm></scoped-elm>`,
};
}

render() {
return html`<slot name="template"></slot>`;
}
},
);

const tag = unsafeStatic(tagName);
await fixture(html`<${tag}></${tag}>`);

expect(createElementSpy.getCalls()).to.have.length(1);
});
102 changes: 0 additions & 102 deletions packages/ui/components/core/test/SlotMixin.test.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
import sinon from 'sinon';
import { defineCE, expect, fixture, fixtureSync, unsafeStatic, html } from '@open-wc/testing';
import { ScopedElementsMixin } from '@open-wc/scoped-elements/lit-element.js';
import { SlotMixin } from '@lion/ui/core.js';
import { LitElement } from 'lit';

/**
* @typedef {import('../types/SlotMixinTypes.js').SlotHost} SlotHost
*/

// @ts-ignore
const createElementNative = ShadowRoot.prototype.createElement;
function mockScopedRegistry() {
const outputObj = { createElementCallCount: 0 };
// @ts-expect-error wait for browser support
ShadowRoot.prototype.createElement = (tagName, options) => {
outputObj.createElementCallCount += 1;
// Return an element that lit can use as render target
return createElementNative(tagName, options);
};
return outputObj;
}

function unMockScopedRegistry() {
// @ts-expect-error wait for browser support
ShadowRoot.prototype.createElement = createElementNative;
}

describe('SlotMixin', () => {
it('inserts provided element into light dom and sets slot', async () => {
const tag = defineCE(
Expand Down Expand Up @@ -566,86 +546,4 @@ describe('SlotMixin', () => {
expect(el._templateNode.textContent).to.equal('1');
});
});

describe('Scoped Registries', () => {
it('supports scoped elements when polyfill loaded', async () => {
const outputObj = mockScopedRegistry();

class ScopedEl extends LitElement {}

const tagName = defineCE(
// @ts-ignore
class extends ScopedElementsMixin(SlotMixin(LitElement)) {
static get scopedElements() {
return {
// @ts-expect-error
...super.scopedElements,
'scoped-elm': ScopedEl,
};
}

get slots() {
return {
...super.slots,
template: () => html`<scoped-elm></scoped-elm>`,
};
}

render() {
return html`<slot name="template"></slot>`;
}
},
);

const tag = unsafeStatic(tagName);
await fixture(html`<${tag}></${tag}>`);

expect(outputObj.createElementCallCount).to.equal(1);

unMockScopedRegistry();
});

it('does not scope elements when polyfill not loaded', async () => {
// @ts-expect-error
ShadowRoot.prototype.createElement = null;
class ScopedEl extends LitElement {}

const tagName = defineCE(
class extends ScopedElementsMixin(SlotMixin(LitElement)) {
static get scopedElements() {
return {
// @ts-expect-error
...super.scopedElements,
'scoped-el': ScopedEl,
};
}

get slots() {
return {
...super.slots,
template: () => html`<scoped-el></scoped-el>`,
};
}

render() {
return html`<slot name="template"></slot>`;
}
},
);

const renderTarget = document.createElement('div');
const el = document.createElement(tagName);

// We don't use fixture, so we limit the amount of calls to document.createElement
const docSpy = sinon.spy(document, 'createElement');
document.body.appendChild(renderTarget);
renderTarget.appendChild(el);

expect(docSpy.callCount).to.equal(2);

document.body.removeChild(renderTarget);
docSpy.restore();
unMockScopedRegistry();
});
});
});
60 changes: 46 additions & 14 deletions web-test-runner.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { playwrightLauncher } from '@web/test-runner-playwright';

const devMode = process.argv.includes('--dev-mode');

const packages = fs
const testGroups = fs
.readdirSync('packages')
.filter(
dir => fs.statSync(`packages/${dir}`).isDirectory() && fs.existsSync(`packages/${dir}/test`),
Expand All @@ -18,21 +18,54 @@ const packages = fs
fs.existsSync(`packages/ui/components/${dir}/test`),
)
.map(dir => ({ name: dir, path: `packages/ui/components/${dir}/test` })),
);
)
.map(pkg => ({
name: pkg.name,
files: `${pkg.path}/**/*.test.js`,
}));

/**
* @type {import('@web/test-runner').TestRunnerConfig['testRunnerHtml']}
*
*/
const testRunnerHtml = testRunnerImport =>
`
const testsThatShouldRunWithScopedCustomElementRegistryPolyfill = testGroups.map(testGroup => {
const files = [
testGroup.files,
`!${testGroup.files.replace('*.test.js', '*.no-polyfill.test.js')}`,
];
return {
name: testGroup.name,
files,
/**
* @type {import('@web/test-runner').TestRunnerConfig['testRunnerHtml']}
*
*/
testRunnerHtml: testRunnerImport => `
<html>
<head>
<script src="/node_modules/@webcomponents/scoped-custom-element-registry/scoped-custom-element-registry.min.js"></script>
<script type="module" src="${testRunnerImport}"></script>
</head>
</html>
`;
`,
};
});

const testsThatShouldNotRunWithPolyfill = testGroups.map(testGroup => {
const files = [testGroup.files, `!${testGroup.files.replace('*.test.js', '*.polyfill.test.js')}`];

return {
name: testGroup.name,
files,
/**
* @type {import('@web/test-runner').TestRunnerConfig['testRunnerHtml']}
*
*/
testRunnerHtml: testRunnerImport => `
<html>
<head>
<script type="module" src="${testRunnerImport}"></script>
</head>
</html>
`,
};
});

export default {
nodeResolve: { exportConditions: [devMode && 'development'] },
Expand All @@ -51,14 +84,13 @@ export default {
timeout: '5000',
},
},
testRunnerHtml,
browsers: [
playwrightLauncher({ product: 'firefox', concurrency: 1 }),
playwrightLauncher({ product: 'chromium' }),
playwrightLauncher({ product: 'webkit' }),
],
groups: packages.map(pkg => ({
name: pkg.name,
files: `${pkg.path}/**/*.test.js`,
})),
groups: [].concat([
...testsThatShouldRunWithScopedCustomElementRegistryPolyfill,
...testsThatShouldNotRunWithPolyfill,
]),
};

0 comments on commit 2e883d6

Please sign in to comment.