diff --git a/.github/workflows/steps.yml b/.github/workflows/steps.yml index 80da76c..b7126d0 100644 --- a/.github/workflows/steps.yml +++ b/.github/workflows/steps.yml @@ -15,7 +15,7 @@ jobs: - run: npm ci - - run: npm test + - run: npm run test:ci env: BROWSER_STACK_USERNAME: ${{ secrets.BROWSER_STACK_USERNAME }} BROWSER_STACK_ACCESS_KEY: ${{ secrets. BROWSER_STACK_ACCESS_KEY }} diff --git a/browserstack-karma.js b/browserstack-karma.js index 63dcd01..bf395bb 100644 --- a/browserstack-karma.js +++ b/browserstack-karma.js @@ -90,6 +90,7 @@ module.exports = { browser_version: "11.0", os: "Windows", os_version: "7", + es5: true, }, BS_IE_10: { base: "BrowserStack", @@ -97,5 +98,6 @@ module.exports = { browser_version: "10.0", os: "Windows", os_version: "7", + es5: true, }, }; diff --git a/karma.conf.js b/karma.conf.js index 1090e4e..571791c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,6 +1,7 @@ const ci = !!process.env.CI; const watch = !!process.env.WATCH; const live = !!process.env.LIVE; +const es5 = !!process.env.ES5; const ip = "bs-local.com"; @@ -9,8 +10,11 @@ const browserstack = require("./browserstack-karma.js"); // https://www.browserstack.com/open-source (text search "parallels") const BROWSERSTACK_OPEN_SOURCE_CONCURRENCY = 5; +const getBrowserstackBrowsers = () => + Object.keys(browserstack).filter((k) => !!browserstack[k].es5 === es5); + const browsers = ci - ? Object.keys(browserstack) + ? getBrowserstackBrowsers() : live ? undefined : watch @@ -43,6 +47,12 @@ module.exports = function (config) { compilerOptions: { ...require("./tsconfig.json").compilerOptions, ...require("./test/tsconfig.json").compilerOptions, + sourceMap: false, + inlineSourceMap: true, + target: es5 ? "es5" : "es6", + }, + bundlerOptions: { + sourceMap: true, }, include: process.env.FILES_PATTERN.split(",").concat("src/**/*.ts"), }, diff --git a/package.json b/package.json index bd44e22..b6ab904 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "unit": "cross-env FILES_PATTERN=\"test/unit/*.ts,test/unit/*.tsx\" karma start karma.conf.js", "benchmark": "cross-env FILES_PATTERN=\"test-bundles/benchmark/**/*.js\" karma start karma.conf.cjs --concurrency=1", "release": "release-it", + "test:ci": "npm test && cross-env ES5=true npm run unit", "test": "npm run build && npm run lint && npm run unit" }, "devDependencies": { diff --git a/test/unit/core.ts b/test/unit/core.ts index 0b84930..3208ce1 100644 --- a/test/unit/core.ts +++ b/test/unit/core.ts @@ -41,15 +41,7 @@ function map(fn: any, list: any[]) { const inner = prop("innerHTML"); -class A extends HTMLParagraphElement {} -class B extends HTMLParagraphElement {} - describe("snabbdom", function () { - before(function () { - customElements.define("p-a", A, { extends: "p" }); - customElements.define("p-b", B, { extends: "p" }); - }); - let elm: any, vnode0: any; beforeEach(function () { elm = document.createElement("div"); @@ -199,13 +191,11 @@ describe("snabbdom", function () { it("handles classes from both selector and property", function () { elm = patch(vnode0, h("div", [h("i.has", { class: { classes: true } })])) .elm; - assert(elm.firstChild.classList.contains("has")); - assert(elm.firstChild.classList.contains("classes")); - }); - it("can create custom elements", function () { - const vnode1 = h("p", { is: "p-a" }); - elm = patch(vnode0, vnode1).elm; - assert(elm instanceof A); + assert(elm.firstChild.classList.contains("has"), "has `has` class"); + assert( + elm.firstChild.classList.contains("classes"), + "has `classes` class" + ); }); it("can create elements with text content", function () { elm = patch(vnode0, h("div", ["I am a string"])).elm; @@ -378,14 +368,52 @@ describe("snabbdom", function () { patch(vnode1, vnode2); assert.strictEqual((elm as any).a, "foo"); }); - it("handles changing is attribute", function () { - const vnode1 = h("p", { is: "p-a" }); - const vnode2 = h("p", { is: "p-b" }); + describe("custom elements", function () { + if ("customElements" in window) { + describe("customized built-in element", function () { + const isSafari = /^((?!chrome|android).)*safari/i.test( + navigator.userAgent + ); - elm = patch(vnode0, vnode1).elm; - assert(elm instanceof A); - elm = patch(vnode1, vnode2).elm; - assert(elm instanceof B); + if (!isSafari) { + class A extends HTMLParagraphElement {} + class B extends HTMLParagraphElement {} + + before(function () { + if ("customElements" in window) { + customElements.define("p-a", A, { extends: "p" }); + customElements.define("p-b", B, { extends: "p" }); + } + }); + it("can create custom elements", function () { + if ("customElements" in window) { + const vnode1 = h("p", { is: "p-a" }); + elm = patch(vnode0, vnode1).elm; + assert(elm instanceof A); + } else { + this.skip(); + } + }); + it("handles changing is attribute", function () { + const vnode1 = h("p", { is: "p-a" }); + const vnode2 = h("p", { is: "p-b" }); + + elm = patch(vnode0, vnode1).elm; + assert(elm instanceof A); + elm = patch(vnode1, vnode2).elm; + assert(elm instanceof B); + }); + } else { + it.skip("safari does not support customized built-in elements", () => { + assert(false); + }); + } + }); + } else { + it.skip("browser does not support custom elements", () => { + assert(false); + }); + } }); describe("using toVNode()", function () { it("can remove previous children of the root element", function () {