diff --git a/.eslintignore b/.eslintignore index 01c4ce1..46e7276 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ html scripts/ docs/ **/.eslintrc.js -commitlint.config.js \ No newline at end of file +commitlint.config.js +cypress.config.ts diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index d541545..02e932d 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.13] + node-version: [20.x] steps: - uses: actions/checkout@v2 @@ -35,7 +35,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.x] + node-version: [20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: @@ -54,7 +54,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.13] + node-version: [20.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 0000000..d4933b3 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from 'cypress'; + +export default defineConfig({ + includeShadowDom: true, + projectId: '1tfaog', + e2e: { + // We've imported your old cypress plugins here. + // You may want to clean this up later by importing these. + setupNodeEvents(on, config) { + return require('./cypress/plugins/index.ts')(on, config); + }, + baseUrl: 'http://localhost:3999/', + specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', + experimentalRunAllSpecs: true, + }, +}); diff --git a/cypress.json b/cypress.json deleted file mode 100644 index 748d2a1..0000000 --- a/cypress.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://on.cypress.io/cypress.schema.json", - "baseUrl": "http://localhost:3999/", - "includeShadowDom": true, - "projectId": "1tfaog" -} diff --git a/cypress/integration/components/button.spec.ts b/cypress/e2e/components/button.spec.ts similarity index 100% rename from cypress/integration/components/button.spec.ts rename to cypress/e2e/components/button.spec.ts diff --git a/cypress/e2e/components/input.spec.ts b/cypress/e2e/components/input.spec.ts new file mode 100644 index 0000000..dd004cb --- /dev/null +++ b/cypress/e2e/components/input.spec.ts @@ -0,0 +1,55 @@ +import { ionInputCypress } from '@lib'; +import * as testHelpers from '../../../test-helpers/test-helpers.js'; + +describe('Ion Input', () => { + const selectors = [ + '.external-label ion-input', + '.internal-label ion-input', + '.internal-label ion-input', + '.internal-aria-label ion-input', + ]; + + selectors.forEach((selector) => { + describe(selector, () => { + beforeEach(() => { + cy.visit('./ion-input.html'); + }); + + it('can be written on by string selector', () => { + cy.get(`${selector}.hydrated`) + .first() + .then(($ionInput) => { + const element = $ionInput[0]; + const wantedText = testHelpers.convertToTestString( + element.innerText + ); + + ionInputCypress.write(selector, wantedText).then(() => { + const inputElement = element.querySelector('input')?.value; + + expect(inputElement).to.eq(wantedText); + }); + }); + }); + + it('can be cleared', () => { + cy.get(`${selector}.hydrated`) + .first() + .then(($ionInput) => { + const element = $ionInput[0]; + + ionInputCypress + .write(selector, 'i am not clear here :)') + .then(() => { + return ionInputCypress.clear(selector); + }) + .then(() => { + const inputElement = element.querySelector('input')?.value; + + expect(inputElement).to.eq(''); + }); + }); + }); + }); + }); +}); diff --git a/cypress/integration/components/range.spec.ts b/cypress/e2e/components/range.spec.ts similarity index 95% rename from cypress/integration/components/range.spec.ts rename to cypress/e2e/components/range.spec.ts index 2d2b0af..9ae6e91 100644 --- a/cypress/integration/components/range.spec.ts +++ b/cypress/e2e/components/range.spec.ts @@ -26,7 +26,7 @@ const selectorAndValues: Array<{ describe('using valid valid ranges', () => { beforeEach(() => { - cy.visit('./'); + cy.visit('./ion-range.html'); }); selectorAndValues.forEach((selectorAndValue) => { @@ -125,7 +125,7 @@ describe('using it to values beyond their supported max/min does not hangs', () ]; beforeEach(() => { - cy.visit('./'); + cy.visit('./ion-range.html'); }); outOfRangeValues.forEach((selectorAndValue) => { diff --git a/cypress/integration/components/select.spec.ts b/cypress/e2e/components/select.spec.ts similarity index 67% rename from cypress/integration/components/select.spec.ts rename to cypress/e2e/components/select.spec.ts index 1d6602d..a5a092a 100644 --- a/cypress/integration/components/select.spec.ts +++ b/cypress/e2e/components/select.spec.ts @@ -2,7 +2,7 @@ import { ionSelectCypress } from '@lib'; describe('IonSelect', () => { beforeEach(() => { - cy.visit('./'); + cy.visit('./ion-select.html'); }); const byInterfaceSelectors = [ @@ -44,21 +44,39 @@ describe('IonSelect', () => { const byTextWithSelectors: Array<{ elementSelector: string; text: string }> = [ { - elementSelector: 'ion-select[interface=alert]', - text: 'ion-select ion-alert', + elementSelector: + 'ion-select#ion-select-ion-alert-external-label[interface=alert]', + text: 'ion-select ion-alert external-label', }, { - elementSelector: 'ion-select[interface=action-sheet]', - text: 'ion-select ion-action-sheet', + elementSelector: + 'ion-select#ion-select-ion-action-sheet-external-label[interface=action-sheet]', + text: 'ion-select ion-action-sheet external-label', }, { - elementSelector: 'ion-select[interface=popover]', - text: 'ion-select ion-popover', + elementSelector: + 'ion-select#ion-select-ion-popover-external-label[interface=popover]', + text: 'ion-select ion-popover external-label', + }, + { + elementSelector: + 'ion-select#ion-select-ion-alert-internal-label[interface=alert]', + text: 'ion-select ion-alert internal-label', + }, + { + elementSelector: + 'ion-select#ion-select-ion-action-sheet-internal-label[interface=action-sheet]', + text: 'ion-select ion-action-sheet internal-label', + }, + { + elementSelector: + 'ion-select#ion-select-ion-popover-internal-label[interface=popover]', + text: 'ion-select ion-popover internal-label', }, ]; byTextWithSelectors.forEach((textAndSelector) => { - describe(`find ${textAndSelector.elementSelector} using text`, () => { + describe(`find ${textAndSelector.text} using text`, () => { it(`can be found with "${textAndSelector.text}"`, () => { cy.get(textAndSelector.elementSelector) .should('have.length', 1) // check that just one is tested diff --git a/cypress/integration/get-from-supported-selector.spec.ts b/cypress/e2e/get-from-supported-selector.spec.ts similarity index 100% rename from cypress/integration/get-from-supported-selector.spec.ts rename to cypress/e2e/get-from-supported-selector.spec.ts diff --git a/cypress/integration/components/input.spec.ts b/cypress/integration/components/input.spec.ts deleted file mode 100644 index 3f7e5f6..0000000 --- a/cypress/integration/components/input.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ionInputCypress } from '@lib'; -import * as testHelpers from '../../../test-helpers/test-helpers.js'; - -describe('Ion Input', () => { - const selector = 'ion-input'; - beforeEach(() => { - cy.visit('./'); - }); - - it('can be written on by string selector', () => { - cy.get(selector) - .first() - .then(($ionInput) => { - const element = $ionInput[0]; - const wantedText = testHelpers.convertToTestString(element.innerText); - - ionInputCypress.write(selector, wantedText).then(() => { - const inputElement = element.querySelector('input')?.value; - - expect(inputElement).to.eq(wantedText); - }); - }); - }); - - it('can be cleared', () => { - cy.get(selector) - .first() - .then(($ionInput) => { - const element = $ionInput[0]; - - ionInputCypress - .write(selector, 'i am not clear here :)') - .then(() => { - return ionInputCypress.clear(selector); - }) - .then(() => { - const inputElement = element.querySelector('input')?.value; - - expect(inputElement).to.eq(''); - }); - }); - }); -}); diff --git a/cypress/support/index.ts b/cypress/support/e2e.ts similarity index 94% rename from cypress/support/index.ts rename to cypress/support/e2e.ts index d68db96..63630b6 100644 --- a/cypress/support/index.ts +++ b/cypress/support/e2e.ts @@ -1,20 +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') +// *********************************************************** +// 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/html/assets/ion-range.mjs b/html/assets/ion-range.mjs new file mode 100644 index 0000000..a486a86 --- /dev/null +++ b/html/assets/ion-range.mjs @@ -0,0 +1,36 @@ +import { defineCustomElements } from '/node_modules/@ionic/core/dist/esm/loader.js'; +import { convertToTestString } from '/test-helpers/test-helpers.js'; + +defineCustomElements(window).then(() => { + /* Ionic is loaded! */ + + // ------ ION RANGE ----- // + const ranges = document.querySelectorAll('ion-range'); + const rangesIntervals = new Array(ranges.length); + document.querySelectorAll('ion-range').forEach((ionRange, i) => { + ionRange.addEventListener('ionChange', (event) => { + // console.log('ionRange ionChange event', event); + clearInterval(rangesIntervals[i]); + const targetIonRange = event.target; + + rangesIntervals[i] = setInterval(() => { + const slot = + targetIonRange.shadowRoot.querySelector('slot[name="end"]'); + if (!slot) { + return; + } + + clearInterval(rangesIntervals[i]); + rangesIntervals[i] = undefined; + + let eventValue = event.detail.value; + + if (typeof eventValue === 'object') { + eventValue = `${eventValue.lower}/${eventValue.upper}`; + } + + slot.assignedNodes()[0].innerText = eventValue; + }, 100); + }); + }); +}); diff --git a/html/assets/ion-select.mjs b/html/assets/ion-select.mjs new file mode 100644 index 0000000..1539a43 --- /dev/null +++ b/html/assets/ion-select.mjs @@ -0,0 +1,5 @@ +import { defineCustomElements } from '/node_modules/@ionic/core/dist/esm/loader.js'; + +defineCustomElements(window).then(() => { + /* Ionic is loaded! */ +}); diff --git a/html/assets/scripts.mjs b/html/assets/scripts.mjs index 9519f39..b6a785e 100644 --- a/html/assets/scripts.mjs +++ b/html/assets/scripts.mjs @@ -7,39 +7,4 @@ defineCustomElements(window).then(() => { document.querySelector('ion-button').addEventListener('click', (event) => { event.target.innerText = convertToTestString(event.target.innerText); }); - - document.querySelector('.ion-range-dual ion-range').value = { - lower: -50, - upper: 50, - }; - - // ------ ION RANGE ----- // - const ranges = document.querySelectorAll('ion-range'); - const rangesIntervals = new Array(ranges.length); - document.querySelectorAll('ion-range').forEach((ionRange, i) => { - ionRange.addEventListener('ionChange', (event) => { - console.log('ionRange ionChange event', event); - clearInterval(rangesIntervals[i]); - const targetIonRange = event.target; - - rangesIntervals[i] = setInterval(() => { - const slot = - targetIonRange.shadowRoot.querySelector('slot[name="end"]'); - if (!slot) { - return; - } - - clearInterval(rangesIntervals[i]); - rangesIntervals[i] = undefined; - - let eventValue = event.detail.value; - - if (typeof eventValue === 'object') { - eventValue = `${eventValue.lower}/${eventValue.upper}`; - } - - slot.assignedNodes()[0].innerText = eventValue; - }, 100); - }); - }); }); diff --git a/html/assets/style.css b/html/assets/style.css index d3a2716..ac19de4 100644 --- a/html/assets/style.css +++ b/html/assets/style.css @@ -13,3 +13,8 @@ main { max-width: 500px; width: 80%; } + +h1, +h2 { + color: white; +} diff --git a/html/index.html b/html/index.html index b251d76..b573736 100644 --- a/html/index.html +++ b/html/index.html @@ -21,10 +21,12 @@