diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index acdc0799..69a4644f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,4 +27,4 @@ jobs: - run: npm run build --if-present - - run: npm run test + - run: npm run test:unit diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 00000000..40e23f7e --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,27 @@ +name: Playwright Tests +on: + push: + branches: [main, master, develop, "feature/**"] + pull_request: + branches: [main, master] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.gitignore b/.gitignore index 59910fa5..23e10e36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,54 +1,42 @@ -# Windows image file caches Thumbs.db ehthumbs.db -# Folder config file Desktop.ini -# Recycle Bin used on file shares $RECYCLE.BIN/ -# Windows Installer files *.cab *.msi *.msm *.msp -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - .DS_Store .AppleDouble .LSOverride -# Icon must end with two \r Icon - -# Thumbnails ._* -# Files that might appear on external disk .Spotlight-V100 .Trashes -# Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk -# Editor files .idea -# Node modules node_modules -# Jekyll! _site -.sass-cache \ No newline at end of file +.sass-cache + +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ + +coverage \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 53df447f..b592551a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Version 19 +#### 19.1.0 + +- Added end to end tests to expand test coverage to more use cases and cross browser + #### 19.0.5 - Removed `.eslintrc.json`, `LICENSE`, `CHANGELOG.md`, `CODE_OF_CONDUCT.md`, `README.md`, `package.json` from the package files, as they didn't have any impact on [code quality](https://docs.npmjs.com/searching-for-and-choosing-packages-to-download#quality). diff --git a/README.md b/README.md index a9f8a561..d459ab25 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ Please note that the video poster can be lazily loaded too. ## 👩‍💻 Getting started - Script -The latest, recommended version of LazyLoad is **19.0.5**. +The latest, recommended version of LazyLoad is **19.1.0**. Note that if you need to support Internet Explorer 11, you need to use version 17.9.0 or below. Quickly understand how to upgrade from a previous version reading the [practical upgrade guide](UPGRADE.md). @@ -186,7 +186,7 @@ Quickly understand how to upgrade from a previous version reading the [practical The easiest way to use LazyLoad is to include the script from a CDN. ```html - + ``` OR, if you prefer to import it as an ES module: @@ -237,7 +237,7 @@ Then include the script. ```html ``` @@ -271,7 +271,7 @@ Then include the script. ```html ``` diff --git a/demos/async.html b/demos/async.html index 39a02292..118d4d78 100644 --- a/demos/async.html +++ b/demos/async.html @@ -47,7 +47,7 @@

Async loading demo

>Stivaletti @@ -57,7 +57,7 @@

Async loading demo

>Open toe @@ -67,7 +67,7 @@

Async loading demo

>Sneakers & Tennis @@ -77,7 +77,7 @@

Async loading demo

>Sneakers & Tennis shoes basse @@ -87,7 +87,7 @@

Async loading demo

>Sneakers & Tennis shoes alte @@ -97,7 +97,7 @@

Async loading demo

>Sneakers & Tennis shoes alte @@ -107,7 +107,7 @@

Async loading demo

>Sneakers & Tennis shoes basse @@ -117,7 +117,7 @@

Async loading demo

>Sneakers & Tennis shoes basse @@ -127,7 +127,7 @@

Async loading demo

>Stivali @@ -137,7 +137,7 @@

Async loading demo

>Stivali @@ -147,7 +147,7 @@

Async loading demo

>Stivaletti @@ -157,7 +157,7 @@

Async loading demo

>Stivaletti @@ -167,7 +167,7 @@

Async loading demo

>Stivali @@ -177,7 +177,7 @@

Async loading demo

>Stivaletti @@ -187,7 +187,7 @@

Async loading demo

>Décolleté @@ -197,7 +197,7 @@

Async loading demo

>Mocassini @@ -207,7 +207,7 @@

Async loading demo

>Stivaletti @@ -217,7 +217,7 @@

Async loading demo

>Décolleté @@ -227,7 +227,7 @@

Async loading demo

>Décolleté @@ -237,7 +237,7 @@

Async loading demo

>Francesine @@ -247,7 +247,7 @@

Async loading demo

>Stivaletti @@ -257,7 +257,7 @@

Async loading demo

>Décolleté @@ -267,7 +267,7 @@

Async loading demo

>Mocassini @@ -277,7 +277,7 @@

Async loading demo

>Mocassini @@ -287,7 +287,7 @@

Async loading demo

>Stivali @@ -297,7 +297,7 @@

Async loading demo

>Stivaletti @@ -307,7 +307,7 @@

Async loading demo

>Stivaletti @@ -317,7 +317,7 @@

Async loading demo

>Mocassini @@ -327,7 +327,7 @@

Async loading demo

>Stivaletti @@ -337,7 +337,7 @@

Async loading demo

>Stivaletti @@ -347,7 +347,7 @@

Async loading demo

>Stivaletti @@ -357,7 +357,7 @@

Async loading demo

>Stivaletti @@ -367,7 +367,7 @@

Async loading demo

>Cuissardes @@ -377,7 +377,7 @@

Async loading demo

>Décolleté @@ -387,7 +387,7 @@

Async loading demo

>Stivaletti @@ -397,7 +397,7 @@

Async loading demo

>Sneakers & Tennis shoes basse @@ -407,7 +407,7 @@

Async loading demo

>Mocassini @@ -417,7 +417,7 @@

Async loading demo

>Sneakers & Tennis shoes basse @@ -427,7 +427,7 @@

Async loading demo

>Mocassini @@ -437,7 +437,7 @@

Async loading demo

>Mocassini @@ -464,7 +464,7 @@

Async loading demo

var callback_error = function (element) { logElementEvent("💀 ERROR", element); element.src = - "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/async_multiple.html b/demos/async_multiple.html index 5b080d45..524d9c11 100644 --- a/demos/async_multiple.html +++ b/demos/async_multiple.html @@ -51,7 +51,7 @@

Async loading, multiple instances demo

Stivaletti @@ -60,7 +60,7 @@

Async loading, multiple instances demo

Open toe @@ -70,7 +70,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis @@ -80,7 +80,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes basse @@ -90,7 +90,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes alte @@ -100,7 +100,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes alte @@ -110,7 +110,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes basse @@ -120,7 +120,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes basse @@ -130,7 +130,7 @@

Async loading, multiple instances demo

>Stivali @@ -140,7 +140,7 @@

Async loading, multiple instances demo

>Stivali @@ -150,7 +150,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -160,7 +160,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -170,7 +170,7 @@

Async loading, multiple instances demo

>Stivali @@ -180,7 +180,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -190,7 +190,7 @@

Async loading, multiple instances demo

>Décolleté @@ -200,7 +200,7 @@

Async loading, multiple instances demo

>Mocassini @@ -210,7 +210,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -220,7 +220,7 @@

Async loading, multiple instances demo

>Décolleté @@ -230,7 +230,7 @@

Async loading, multiple instances demo

>Décolleté @@ -243,7 +243,7 @@

Async loading, multiple instances demo

Francesine @@ -252,7 +252,7 @@

Async loading, multiple instances demo

Stivaletti @@ -262,7 +262,7 @@

Async loading, multiple instances demo

>Décolleté @@ -272,7 +272,7 @@

Async loading, multiple instances demo

>Mocassini @@ -282,7 +282,7 @@

Async loading, multiple instances demo

>Mocassini @@ -292,7 +292,7 @@

Async loading, multiple instances demo

>Stivali @@ -302,7 +302,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -312,7 +312,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -322,7 +322,7 @@

Async loading, multiple instances demo

>Mocassini @@ -332,7 +332,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -342,7 +342,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -352,7 +352,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -362,7 +362,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -372,7 +372,7 @@

Async loading, multiple instances demo

>Cuissardes @@ -382,7 +382,7 @@

Async loading, multiple instances demo

>Décolleté @@ -392,7 +392,7 @@

Async loading, multiple instances demo

>Stivaletti @@ -402,7 +402,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes basse @@ -412,7 +412,7 @@

Async loading, multiple instances demo

>Mocassini @@ -422,7 +422,7 @@

Async loading, multiple instances demo

>Sneakers & Tennis shoes basse @@ -432,7 +432,7 @@

Async loading, multiple instances demo

>Mocassini @@ -442,7 +442,7 @@

Async loading, multiple instances demo

>Mocassini @@ -471,7 +471,7 @@

Async loading, multiple instances demo

var callback_error = function (element) { logElementEvent("💀 ERROR", element); element.src = - "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/background_images.html b/demos/background_images.html index 420d9211..67b80738 100644 --- a/demos/background_images.html +++ b/demos/background_images.html @@ -35,297 +35,297 @@

Background images demo

  • - +
  • - +
  • - +
  • @@ -350,8 +350,7 @@

    Background images demo

    }; var callback_error = function (element) { logElementEvent("💀 ERROR", element); - element.style.backgroundImage = - "url('https://via.placeholder.com/440x560/?text=Error+Placeholder')"; + element.style.backgroundImage = 'url("./images/440x560-Error.webp")'; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/background_images_image-set.html b/demos/background_images_image-set.html index 2a1a0ff9..c5fa134a 100644 --- a/demos/background_images_image-set.html +++ b/demos/background_images_image-set.html @@ -35,13 +35,9 @@

    Background images with image-set demo

    @@ -51,20 +47,13 @@

    Background images with image-set demo

    class="multiple" href="#" style=" - background-image: -webkit-image-set( - url('https://via.placeholder.com/220x280?text=Img+02+Left') 1x, - url('https://via.placeholder.com/440x560?text=Img+02+Left') 2x - ), -webkit-image-set( - url('https://via.placeholder.com/220x280?text=Img+02+Right') 1x, - url('https://via.placeholder.com/440x560?text=Img+02+Right') 2x - ); background-image: image-set( - url('https://via.placeholder.com/220x280?text=Img+02+Left') 1x, - url('https://via.placeholder.com/440x560?text=Img+02+Left') 2x + url('./images/220x280-L-02.webp') 1x, + url('./images/440x560-L-02.webp') 2x ), image-set( - url('https://via.placeholder.com/220x280?text=Img+02+Right') 1x, - url('https://via.placeholder.com/440x560?text=Img+02+Right') 2x + url('./images/220x280-R-02.webp') 1x, + url('./images/440x560-R-02.webp') 2x ); " > @@ -73,262 +62,259 @@

    Background images with image-set demo

  • @@ -353,8 +339,7 @@

    Background images with image-set demo

    }; var callback_error = function (element) { logElementEvent("💀 ERROR", element); - element.style.backgroundImage = - "url('https://via.placeholder.com/440x560/?text=Error+Placeholder')"; + element.style.backgroundImage = 'url("./images/440x560-Error.webp")'; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/background_images_multi.html b/demos/background_images_multi.html index c35cd227..2c80a7fc 100644 --- a/demos/background_images_multi.html +++ b/demos/background_images_multi.html @@ -2,9 +2,7 @@ - - Multiple background images - Lazyload demos - + Multiple background images - Lazyload demos - + /* Fixes Firefox anomaly during image load */ + @-moz-document url-prefix() { + img:-moz-loading { + visibility: hidden; + } + } + + - -

    Native lazy loading demo

    -

    - You can use this page to test browsers' implementations of - native lazy loading.
    - Please note that not even one line of JavaScript code is involved here. -

    -
    - -
    - - - - - + +

    Native lazy loading demo

    +

    + You can use this page to test browsers' implementations of + native lazy loading.
    + Please note that not even one line of JavaScript code is involved here. +

    +
    + +
    + + + + + diff --git a/demos/native_lazyload_conditional.html b/demos/native_lazyload_conditional.html index eff1b66b..39a8b986 100644 --- a/demos/native_lazyload_conditional.html +++ b/demos/native_lazyload_conditional.html @@ -51,81 +51,53 @@

    Images

    Iframes

    - - - + + +

    Preload = none

    Preload = metadata

    @@ -150,15 +119,12 @@

    Preload = metadata

    preload="metadata" controls width="620" - data-src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4" - data-poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" + data-src="./videos/1920x1080-02.mp4" + data-poster="./videos/1920x1080-02.webp" > - - - + + + + + + diff --git a/demos/picture_type_webp.html b/demos/picture_type_webp.html deleted file mode 100644 index e6cb5252..00000000 --- a/demos/picture_type_webp.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - - Picture with type attribute in source to conditionally load WebP - - Lazyload demos - - - - - -

    - Picture with type attribute in source to conditionally load WebP demo -

    -
    - -
    - - - - diff --git a/demos/popup_layer.html b/demos/popup_layer.html index 4b362b32..1e87e245 100644 --- a/demos/popup_layer.html +++ b/demos/popup_layer.html @@ -48,7 +48,7 @@

    Popup layer demo

    Stivaletti @@ -57,7 +57,7 @@

    Popup layer demo

    Open toe @@ -67,7 +67,7 @@

    Popup layer demo

    >Sneakers & Tennis @@ -77,7 +77,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes basse @@ -87,7 +87,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes alte @@ -97,7 +97,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes alte @@ -107,7 +107,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes basse @@ -117,7 +117,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes basse @@ -127,7 +127,7 @@

    Popup layer demo

    >Stivali @@ -137,7 +137,7 @@

    Popup layer demo

    >Stivali @@ -147,7 +147,7 @@

    Popup layer demo

    >Stivaletti @@ -157,7 +157,7 @@

    Popup layer demo

    >Stivaletti @@ -167,7 +167,7 @@

    Popup layer demo

    >Stivali @@ -177,7 +177,7 @@

    Popup layer demo

    >Stivaletti @@ -187,7 +187,7 @@

    Popup layer demo

    >Décolleté @@ -197,7 +197,7 @@

    Popup layer demo

    >Mocassini @@ -207,7 +207,7 @@

    Popup layer demo

    >Stivaletti @@ -217,7 +217,7 @@

    Popup layer demo

    >Décolleté @@ -227,7 +227,7 @@

    Popup layer demo

    >Décolleté @@ -237,7 +237,7 @@

    Popup layer demo

    >Francesine @@ -247,7 +247,7 @@

    Popup layer demo

    >Stivaletti @@ -257,7 +257,7 @@

    Popup layer demo

    >Décolleté @@ -267,7 +267,7 @@

    Popup layer demo

    >Mocassini @@ -277,7 +277,7 @@

    Popup layer demo

    >Mocassini @@ -287,7 +287,7 @@

    Popup layer demo

    >Stivali @@ -297,7 +297,7 @@

    Popup layer demo

    >Stivaletti @@ -307,7 +307,7 @@

    Popup layer demo

    >Stivaletti @@ -317,7 +317,7 @@

    Popup layer demo

    >Mocassini @@ -327,7 +327,7 @@

    Popup layer demo

    >Stivaletti @@ -337,7 +337,7 @@

    Popup layer demo

    >Stivaletti @@ -347,7 +347,7 @@

    Popup layer demo

    >Stivaletti @@ -357,7 +357,7 @@

    Popup layer demo

    >Stivaletti @@ -367,7 +367,7 @@

    Popup layer demo

    >Cuissardes @@ -377,7 +377,7 @@

    Popup layer demo

    >Décolleté @@ -387,7 +387,7 @@

    Popup layer demo

    >Stivaletti @@ -397,7 +397,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes basse @@ -407,7 +407,7 @@

    Popup layer demo

    >Mocassini @@ -417,7 +417,7 @@

    Popup layer demo

    >Sneakers & Tennis shoes basse @@ -427,7 +427,7 @@

    Popup layer demo

    >Mocassini @@ -437,7 +437,7 @@

    Popup layer demo

    >Mocassini @@ -467,7 +467,7 @@

    Popup layer demo

    var callback_error = function (element) { logElementEvent("💀 ERROR", element); element.src = - "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/print.html b/demos/print.html index b99ae940..d660c9f4 100644 --- a/demos/print.html +++ b/demos/print.html @@ -85,7 +85,7 @@

    Print demo

    Stivaletti @@ -95,7 +95,7 @@

    Print demo

    Open toe @@ -105,7 +105,7 @@

    Print demo

    Sneakers & Tennis @@ -116,7 +116,7 @@

    Print demo

    Sneakers & Tennis shoes basse @@ -127,7 +127,7 @@

    Print demo

    Sneakers & Tennis shoes alte @@ -138,7 +138,7 @@

    Print demo

    Sneakers & Tennis shoes alte @@ -149,7 +149,7 @@

    Print demo

    Sneakers & Tennis shoes basse @@ -160,7 +160,7 @@

    Print demo

    Sneakers & Tennis shoes basse @@ -171,7 +171,7 @@

    Print demo

    Stivali @@ -182,7 +182,7 @@

    Print demo

    Stivali @@ -193,7 +193,7 @@

    Print demo

    Stivaletti @@ -204,7 +204,7 @@

    Print demo

    Stivaletti @@ -215,7 +215,7 @@

    Print demo

    Stivali @@ -226,7 +226,7 @@

    Print demo

    Stivaletti @@ -237,7 +237,7 @@

    Print demo

    Décolleté @@ -248,7 +248,7 @@

    Print demo

    Mocassini @@ -259,7 +259,7 @@

    Print demo

    Stivaletti @@ -270,7 +270,7 @@

    Print demo

    Décolleté @@ -281,7 +281,7 @@

    Print demo

    Décolleté @@ -292,7 +292,7 @@

    Print demo

    Francesine @@ -303,7 +303,7 @@

    Print demo

    Stivaletti @@ -314,7 +314,7 @@

    Print demo

    Décolleté @@ -325,7 +325,7 @@

    Print demo

    Mocassini @@ -336,7 +336,7 @@

    Print demo

    Mocassini @@ -347,7 +347,7 @@

    Print demo

    Stivali @@ -358,7 +358,7 @@

    Print demo

    Stivaletti @@ -369,7 +369,7 @@

    Print demo

    Stivaletti @@ -380,7 +380,7 @@

    Print demo

    Mocassini @@ -391,7 +391,7 @@

    Print demo

    Stivaletti @@ -402,7 +402,7 @@

    Print demo

    Stivaletti @@ -413,7 +413,7 @@

    Print demo

    Stivaletti @@ -424,7 +424,7 @@

    Print demo

    Stivaletti @@ -435,7 +435,7 @@

    Print demo

    Cuissardes @@ -446,7 +446,7 @@

    Print demo

    Décolleté @@ -457,7 +457,7 @@

    Print demo

    Stivaletti @@ -468,7 +468,7 @@

    Print demo

    Sneakers & Tennis shoes basse @@ -479,7 +479,7 @@

    Print demo

    Mocassini @@ -490,7 +490,7 @@

    Print demo

    Sneakers & Tennis shoes basse @@ -501,7 +501,7 @@

    Print demo

    Mocassini @@ -512,7 +512,7 @@

    Print demo

    Mocassini @@ -546,7 +546,7 @@

    Print demo

    var callback_error = function (element) { logElementEvent("💀 ERROR", element); element.src = - "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + "./images/440x560-Error.webp"; }; var callback_cancel = function (element) { logElementEvent("🔥 CANCEL", element); diff --git a/demos/restore_destroy.html b/demos/restore_destroy.html index 01b570d9..1b6ec658 100644 --- a/demos/restore_destroy.html +++ b/demos/restore_destroy.html @@ -52,7 +52,7 @@

    Restore and Destroy demo

    Stivaletti @@ -61,7 +61,7 @@

    Restore and Destroy demo

    Open toe @@ -71,7 +71,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis @@ -81,7 +81,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes basse @@ -91,7 +91,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes alte @@ -101,7 +101,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes alte @@ -111,7 +111,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes basse @@ -121,7 +121,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes basse @@ -131,7 +131,7 @@

    Restore and Destroy demo

    >Stivali @@ -141,7 +141,7 @@

    Restore and Destroy demo

    >Stivali @@ -151,7 +151,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -161,7 +161,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -171,7 +171,7 @@

    Restore and Destroy demo

    >Stivali @@ -181,7 +181,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -191,7 +191,7 @@

    Restore and Destroy demo

    >Décolleté @@ -201,7 +201,7 @@

    Restore and Destroy demo

    >Mocassini @@ -211,7 +211,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -221,7 +221,7 @@

    Restore and Destroy demo

    >Décolleté @@ -231,7 +231,7 @@

    Restore and Destroy demo

    >Décolleté @@ -241,7 +241,7 @@

    Restore and Destroy demo

    >Francesine @@ -251,7 +251,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -261,7 +261,7 @@

    Restore and Destroy demo

    >Décolleté @@ -271,7 +271,7 @@

    Restore and Destroy demo

    >Mocassini @@ -281,7 +281,7 @@

    Restore and Destroy demo

    >Mocassini @@ -291,7 +291,7 @@

    Restore and Destroy demo

    >Stivali @@ -301,7 +301,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -311,7 +311,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -321,7 +321,7 @@

    Restore and Destroy demo

    >Mocassini @@ -331,7 +331,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -341,7 +341,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -351,7 +351,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -361,7 +361,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -371,7 +371,7 @@

    Restore and Destroy demo

    >Cuissardes @@ -381,7 +381,7 @@

    Restore and Destroy demo

    >Décolleté @@ -391,7 +391,7 @@

    Restore and Destroy demo

    >Stivaletti @@ -401,7 +401,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes basse @@ -411,7 +411,7 @@

    Restore and Destroy demo

    >Mocassini @@ -421,7 +421,7 @@

    Restore and Destroy demo

    >Sneakers & Tennis shoes basse @@ -431,7 +431,7 @@

    Restore and Destroy demo

    >Mocassini @@ -441,7 +441,7 @@

    Restore and Destroy demo

    >Mocassini @@ -469,7 +469,7 @@

    Restore and Destroy demo

    }; var callback_error = function (element) { logElementEvent("💀 ERROR", element); - element.src = "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + element.src = "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/sliders_css_only.html b/demos/sliders_css_only.html index 0df0466e..adc809b2 100644 --- a/demos/sliders_css_only.html +++ b/demos/sliders_css_only.html @@ -1,4 +1,4 @@ -o + @@ -59,8 +59,8 @@

    Swipey, CSS only

    Stivaletti @@ -68,8 +68,8 @@

    Swipey, CSS only

    Stivaletti @@ -77,8 +77,8 @@

    Swipey, CSS only

    Stivaletti @@ -86,8 +86,8 @@

    Swipey, CSS only

    Stivaletti @@ -95,8 +95,8 @@

    Swipey, CSS only

    Stivaletti @@ -110,8 +110,8 @@

    Swipey, CSS only

    Stivaletti @@ -119,8 +119,8 @@

    Swipey, CSS only

    Stivaletti @@ -128,8 +128,8 @@

    Swipey, CSS only

    Stivaletti @@ -137,8 +137,8 @@

    Swipey, CSS only

    Stivaletti @@ -146,8 +146,8 @@

    Swipey, CSS only

    Stivaletti @@ -161,8 +161,8 @@

    Swipey, CSS only

    Stivaletti @@ -170,8 +170,8 @@

    Swipey, CSS only

    Stivaletti @@ -179,8 +179,8 @@

    Swipey, CSS only

    Stivaletti @@ -188,8 +188,8 @@

    Swipey, CSS only

    Stivaletti @@ -197,8 +197,8 @@

    Swipey, CSS only

    Stivaletti @@ -212,8 +212,8 @@

    Swipey, CSS only

    Stivaletti @@ -221,8 +221,8 @@

    Swipey, CSS only

    Stivaletti @@ -230,8 +230,8 @@

    Swipey, CSS only

    Stivaletti @@ -239,8 +239,8 @@

    Swipey, CSS only

    Stivaletti @@ -248,8 +248,8 @@

    Swipey, CSS only

    Stivaletti @@ -263,8 +263,8 @@

    Swipey, CSS only

    Stivaletti @@ -272,8 +272,8 @@

    Swipey, CSS only

    Stivaletti @@ -281,8 +281,8 @@

    Swipey, CSS only

    Stivaletti @@ -290,8 +290,8 @@

    Swipey, CSS only

    Stivaletti @@ -299,8 +299,8 @@

    Swipey, CSS only

    Stivaletti diff --git a/demos/swiper.html b/demos/swiper.html index 07ddeed6..527a79c0 100644 --- a/demos/swiper.html +++ b/demos/swiper.html @@ -52,8 +52,8 @@

    Swiper lazily initialized

    Stivaletti @@ -61,8 +61,8 @@

    Swiper lazily initialized

    Stivaletti @@ -71,8 +71,8 @@

    Swiper lazily initialized

    Stivaletti @@ -81,8 +81,8 @@

    Swiper lazily initialized

    Stivaletti @@ -91,8 +91,8 @@

    Swiper lazily initialized

    Stivaletti @@ -109,8 +109,8 @@

    Swiper lazily initialized

    Stivaletti @@ -119,8 +119,8 @@

    Swiper lazily initialized

    Stivaletti @@ -129,8 +129,8 @@

    Swiper lazily initialized

    Stivaletti @@ -139,8 +139,8 @@

    Swiper lazily initialized

    Stivaletti @@ -149,8 +149,8 @@

    Swiper lazily initialized

    Stivaletti @@ -167,8 +167,8 @@

    Swiper lazily initialized

    Stivaletti @@ -177,8 +177,8 @@

    Swiper lazily initialized

    Stivaletti @@ -187,8 +187,8 @@

    Swiper lazily initialized

    Stivaletti @@ -197,8 +197,8 @@

    Swiper lazily initialized

    Stivaletti @@ -207,8 +207,8 @@

    Swiper lazily initialized

    Stivaletti @@ -225,8 +225,8 @@

    Swiper lazily initialized

    Stivaletti @@ -235,8 +235,8 @@

    Swiper lazily initialized

    Stivaletti @@ -245,8 +245,8 @@

    Swiper lazily initialized

    Stivaletti @@ -255,8 +255,8 @@

    Swiper lazily initialized

    Stivaletti @@ -265,8 +265,8 @@

    Swiper lazily initialized

    Stivaletti @@ -283,8 +283,8 @@

    Swiper lazily initialized

    Stivaletti @@ -293,8 +293,8 @@

    Swiper lazily initialized

    Stivaletti @@ -303,8 +303,8 @@

    Swiper lazily initialized

    Stivaletti @@ -313,8 +313,8 @@

    Swiper lazily initialized

    Stivaletti @@ -323,8 +323,8 @@

    Swiper lazily initialized

    Stivaletti diff --git a/demos/thresholds.html b/demos/thresholds.html index 5bebe0e0..09ae2ccf 100644 --- a/demos/thresholds.html +++ b/demos/thresholds.html @@ -56,7 +56,7 @@

    Threshold and thresholds demo

    Stivaletti @@ -65,7 +65,7 @@

    Threshold and thresholds demo

    Open toe @@ -76,7 +76,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis @@ -87,7 +87,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes basse @@ -97,7 +97,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes alte @@ -107,7 +107,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes alte @@ -118,7 +118,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes basse @@ -129,7 +129,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes basse @@ -139,7 +139,7 @@

    Threshold and thresholds demo

    >Stivali @@ -149,7 +149,7 @@

    Threshold and thresholds demo

    >Stivali @@ -159,7 +159,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -169,7 +169,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -185,7 +185,7 @@

    Threshold and thresholds demo

    Francesine @@ -194,7 +194,7 @@

    Threshold and thresholds demo

    Stivaletti @@ -204,7 +204,7 @@

    Threshold and thresholds demo

    >Décolleté @@ -214,7 +214,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -224,7 +224,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -234,7 +234,7 @@

    Threshold and thresholds demo

    >Stivali @@ -244,7 +244,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -254,7 +254,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -264,7 +264,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -274,7 +274,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -284,7 +284,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -294,7 +294,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -304,7 +304,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -314,7 +314,7 @@

    Threshold and thresholds demo

    >Cuissardes @@ -330,7 +330,7 @@

    Threshold and thresholds demo

    Décolleté @@ -339,7 +339,7 @@

    Threshold and thresholds demo

    Stivaletti @@ -350,7 +350,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes basse @@ -360,7 +360,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -371,7 +371,7 @@

    Threshold and thresholds demo

    >Sneakers & Tennis shoes basse @@ -381,7 +381,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -391,7 +391,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -401,7 +401,7 @@

    Threshold and thresholds demo

    >Stivali @@ -411,7 +411,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -421,7 +421,7 @@

    Threshold and thresholds demo

    >Décolleté @@ -431,7 +431,7 @@

    Threshold and thresholds demo

    >Mocassini @@ -441,7 +441,7 @@

    Threshold and thresholds demo

    >Stivaletti @@ -451,7 +451,7 @@

    Threshold and thresholds demo

    >Décolleté @@ -461,7 +461,7 @@

    Threshold and thresholds demo

    >Décolleté @@ -492,7 +492,7 @@

    Threshold and thresholds demo

    var callback_error = function (element) { logElementEvent("💀 ERROR", element); element.src = - "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/video.html b/demos/video.html index a69987de..e3a330a2 100644 --- a/demos/video.html +++ b/demos/video.html @@ -28,15 +28,12 @@

    Preload = none

    controls preload="none" width="620" - data-src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4" - data-poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" + data-src="./videos/1920x1080-01.mp4" + data-poster="./videos/1920x1080-01.webp" > - - - + + +

    Preload = metadata

    @@ -45,15 +42,12 @@

    Preload = metadata

    preload="metadata" controls width="620" - data-src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4" - data-poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" + data-src="./videos/1920x1080-02.mp4" + data-poster="./videos/1920x1080-02.webp" > - - - + + +

    Preload = auto

    @@ -62,17 +56,14 @@

    Preload = auto

    preload="auto" controls width="620" - data-src="https://archive.org/download/BigBuckBunny_124/Content/big_buck_bunny_720p_surround.mp4" - data-poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217" + data-src="./videos/1920x1080-03.mp4" + data-poster="./videos/1920x1080-03.webp" > - - - + + + - + @@ -97,7 +88,7 @@

    Preload = auto

    }; var callback_error = function (element) { logElementEvent("💀 ERROR", element); - element.src = "https://via.placeholder.com/440x560/?text=Error+Placeholder"; + element.src = "./images/440x560-Error.webp"; }; var callback_finish = function () { logElementEvent("✔️ FINISHED", document.documentElement); diff --git a/demos/videos/1920x1080-01.mp4 b/demos/videos/1920x1080-01.mp4 new file mode 100644 index 00000000..25e98c72 Binary files /dev/null and b/demos/videos/1920x1080-01.mp4 differ diff --git a/demos/videos/1920x1080-01.webp b/demos/videos/1920x1080-01.webp new file mode 100644 index 00000000..52656b59 Binary files /dev/null and b/demos/videos/1920x1080-01.webp differ diff --git a/demos/videos/1920x1080-02.mp4 b/demos/videos/1920x1080-02.mp4 new file mode 100644 index 00000000..969240fa Binary files /dev/null and b/demos/videos/1920x1080-02.mp4 differ diff --git a/demos/videos/1920x1080-02.webp b/demos/videos/1920x1080-02.webp new file mode 100644 index 00000000..54e7e3a8 Binary files /dev/null and b/demos/videos/1920x1080-02.webp differ diff --git a/demos/videos/1920x1080-03.mp4 b/demos/videos/1920x1080-03.mp4 new file mode 100644 index 00000000..36e0aa86 Binary files /dev/null and b/demos/videos/1920x1080-03.mp4 differ diff --git a/demos/videos/1920x1080-03.webp b/demos/videos/1920x1080-03.webp new file mode 100644 index 00000000..a39ec1b0 Binary files /dev/null and b/demos/videos/1920x1080-03.webp differ diff --git a/jest.config.cjs b/jest.config.cjs index 064069a0..fd77b70c 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -1,6 +1,10 @@ -// jest.config.js +/** @type {import('jest').Config} */ module.exports = { - //verbose: true, - testMatch: ["**/__tests__/*.js"], - testEnvironment: "jsdom" + verbose: true, + testMatch: ["/tests/unit/**/*.test.js"], + testEnvironment: 'jsdom', + collectCoverage: true, + collectCoverageFrom: [ + 'src/**/*.js', + ] }; diff --git a/package-lock.json b/package-lock.json index e6802713..9468b834 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,23 @@ { "name": "vanilla-lazyload", - "version": "19.0.5", + "version": "19.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vanilla-lazyload", - "version": "19.0.5", + "version": "19.1.0", "license": "MIT", "devDependencies": { "@babel/core": "^7.24.3", "@babel/preset-env": "^7.24.3", + "@jest/globals": "^29.7.0", + "@playwright/test": "^1.42.1", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", + "@types/node": "^20.12.2", + "http-server": "^14.1.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "rollup": "^4.13.1" @@ -2479,6 +2483,21 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@playwright/test": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz", + "integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==", + "dev": true, + "dependencies": { + "playwright": "1.42.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@rollup/plugin-babel": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", @@ -2881,10 +2900,13 @@ } }, "node_modules/@types/node": { - "version": "16.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz", - "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==", - "dev": true + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/resolve": { "version": "1.20.2", @@ -2957,18 +2979,6 @@ "node": ">=0.4.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3027,6 +3037,15 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3255,6 +3274,24 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3336,6 +3373,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3506,6 +3562,15 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3617,42 +3682,10 @@ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", "dev": true }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -3695,6 +3728,23 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3780,6 +3830,27 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -3856,6 +3927,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -3944,6 +4021,26 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -4005,6 +4102,25 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -4055,6 +4171,18 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -4070,6 +4198,42 @@ "node": ">=4" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -4082,16 +4246,13 @@ "node": ">= 0.4" } }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "dependencies": { - "whatwg-encoding": "^2.0.0" - }, - "engines": { - "node": ">=12" + "bin": { + "he": "bin/he" } }, "node_modules/html-escaper": { @@ -4100,86 +4261,194 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, "engines": { - "node": ">= 6" + "node": ">=8.0.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" + "node": ">=12" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "node_modules/http-server/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/http-server/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/http-server/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">=0.8.19" + "node": ">=7.0.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/http-server/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/http-server/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-server/node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-server/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-server/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4971,6 +5240,201 @@ } } }, + "node_modules/jest-environment-jsdom/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-environment-node": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", @@ -6065,51 +6529,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "acorn": "^8.8.1", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -6176,6 +6595,12 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -6267,6 +6692,18 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -6303,10 +6740,31 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" }, - "engines": { - "node": "*" + "bin": { + "mkdirp": "bin/cmd.js" } }, "node_modules/ms": { @@ -6360,6 +6818,15 @@ "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", "dev": true }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6384,6 +6851,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6537,6 +7013,59 @@ "node": ">=8" } }, + "node_modules/playwright": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz", + "integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==", + "dev": true, + "dependencies": { + "playwright-core": "1.42.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz", + "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -6607,6 +7136,21 @@ } ] }, + "node_modules/qs": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", + "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -6832,6 +7376,12 @@ "node": ">=v12.22.7" } }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -6850,6 +7400,23 @@ "randombytes": "^2.1.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6871,6 +7438,24 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -7117,18 +7702,6 @@ "node": ">=6" } }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -7150,6 +7723,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -7190,6 +7769,18 @@ "node": ">=4" } }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -7229,6 +7820,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -7253,18 +7850,6 @@ "node": ">=10.12.0" } }, - "node_modules/w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", - "dev": true, - "dependencies": { - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -7283,40 +7868,6 @@ "node": ">=12" } }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7422,15 +7973,6 @@ } } }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", @@ -9240,6 +9782,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@playwright/test": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.42.1.tgz", + "integrity": "sha512-Gq9rmS54mjBL/7/MvBaNOBwbfnh7beHvS6oS4srqXFcQHpQCV1+c8JXWE8VLPyRDhgS3H8x8A7hztqI9VnwrAQ==", + "dev": true, + "requires": { + "playwright": "1.42.1" + } + }, "@rollup/plugin-babel": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz", @@ -9506,10 +10057,13 @@ } }, "@types/node": { - "version": "16.9.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz", - "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==", - "dev": true + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/resolve": { "version": "1.20.2", @@ -9572,15 +10126,6 @@ "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -9624,6 +10169,15 @@ "sprintf-js": "~1.0.2" } }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -9802,6 +10356,23 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -9854,6 +10425,19 @@ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, + "call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -9975,6 +10559,12 @@ "browserslist": "^4.23.0" } }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true + }, "create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -10058,38 +10648,10 @@ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", "dev": true }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, - "requires": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" - } - }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -10114,6 +10676,17 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -10174,6 +10747,21 @@ "is-arrayish": "^0.2.1" } }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, "escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -10222,6 +10810,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -10292,6 +10886,12 @@ "path-exists": "^4.0.0" } }, + "follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -10334,6 +10934,19 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -10366,6 +10979,15 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -10378,6 +11000,27 @@ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, "hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -10387,14 +11030,11 @@ "function-bind": "^1.1.2" } }, - "html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "requires": { - "whatwg-encoding": "^2.0.0" - } + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true }, "html-escaper": { "version": "2.0.2", @@ -10402,25 +11042,105 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", "dev": true, "requires": { - "agent-base": "6", - "debug": "4" + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + } } }, "human-signals": { @@ -11033,6 +11753,158 @@ "jest-mock": "^29.7.0", "jest-util": "^29.7.0", "jsdom": "^20.0.0" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + } } }, "jest-environment-node": { @@ -11863,40 +12735,6 @@ "esprima": "^4.0.0" } }, - "jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", - "dev": true, - "requires": { - "abab": "^2.0.6", - "acorn": "^8.8.1", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", - "xml-name-validator": "^4.0.0" - } - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -11942,6 +12780,12 @@ "p-locate": "^4.1.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -12017,6 +12861,12 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -12047,6 +12897,21 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -12092,6 +12957,12 @@ "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", "dev": true }, + "object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -12110,6 +12981,12 @@ "mimic-fn": "^2.1.0" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -12217,6 +13094,44 @@ "find-up": "^4.0.0" } }, + "playwright": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.1.tgz", + "integrity": "sha512-PgwB03s2DZBcNRoW+1w9E+VkLBxweib6KTXM0M3tkiT4jVxKSi6PmVJ591J+0u10LUrgxB7dLRbiJqO5s2QPMg==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.42.1" + } + }, + "playwright-core": { + "version": "1.42.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.1.tgz", + "integrity": "sha512-mxz6zclokgrke9p1vtdy/COWBH+eOZgYUVVU34C73M+4j4HLlQJHtfcqiqqxpP0o8HhMkflvfbquLX5dg6wlfA==", + "dev": true + }, + "portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "requires": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -12264,6 +13179,15 @@ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true }, + "qs": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", + "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "dev": true, + "requires": { + "side-channel": "^1.0.6" + } + }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -12435,6 +13359,12 @@ "xmlchars": "^2.2.0" } }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -12450,6 +13380,20 @@ "randombytes": "^2.1.0" } }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12465,6 +13409,18 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + } + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -12653,15 +13609,6 @@ "url-parse": "^1.5.3" } }, - "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -12674,6 +13621,12 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -12702,6 +13655,15 @@ "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "requires": { + "qs": "^6.4.0" + } + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -12718,6 +13680,12 @@ "picocolors": "^1.0.0" } }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -12739,15 +13707,6 @@ "convert-source-map": "^2.0.0" } }, - "w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", - "dev": true, - "requires": { - "xml-name-validator": "^4.0.0" - } - }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -12763,31 +13722,6 @@ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "dev": true }, - "whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "requires": { - "iconv-lite": "0.6.3" - } - }, - "whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true - }, - "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, - "requires": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - } - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -12857,12 +13791,6 @@ "dev": true, "requires": {} }, - "xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true - }, "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", diff --git a/package.json b/package.json index 97942244..154db278 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vanilla-lazyload", - "version": "19.0.5", + "version": "19.1.0", "description": "LazyLoad is a lightweight (2.4 kB) and flexible script that speeds up your web application by deferring the loading of your below-the-fold images, videos and iframes to when they will enter the viewport. It's written in plain \"vanilla\" JavaScript, it leverages the IntersectionObserver API, it supports responsive images, it optimizes your website for slower connections, and can enable native lazy loading.", "main": "dist/lazyload.min.js", "module": "dist/esm/lazyload.js", @@ -10,18 +10,26 @@ "devDependencies": { "@babel/core": "^7.24.3", "@babel/preset-env": "^7.24.3", + "@jest/globals": "^29.7.0", + "@playwright/test": "^1.42.1", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", - "jest-environment-jsdom": "^29.7.0", + "@types/node": "^20.12.2", "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "http-server": "^14.1.1", "rollup": "^4.13.1" }, "scripts": { + "serve": "npx http-server -p 4200", "build": "rollup -c", "dev": "rollup -c --watch", - "test": "jest", - "devtest": "jest --watch" + "test": "npm run test:unit && npm run test:e2e", + "test:unit": "jest", + "watch-test:unit": "jest --watch", + "test:e2e": "playwright test", + "test-watch:e2e": "npx playwright test --ui" }, "files": [ "dist", diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 00000000..040a6a9b --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,69 @@ +// @ts-check +const { defineConfig, devices } = require('@playwright/test'); + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * @see https://playwright.dev/docs/test-configuration + */ +module.exports = defineConfig({ + testDir: './tests/e2e', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + baseURL: 'http://127.0.0.1:4200/', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + + /* Test against mobile viewports. */ + { + name: 'Mobile Chrome', + use: { ...devices['Pixel 5'] }, + }, + { + name: 'Mobile Safari', + use: { ...devices['iPhone 12'] }, + }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run serve', + url: 'http://127.0.0.1:4200', + reuseExistingServer: !process.env.CI, + }, +}); + diff --git a/tests/e2e/background_image.spec.js b/tests/e2e/background_image.spec.js new file mode 100644 index 00000000..bc3e5682 --- /dev/null +++ b/tests/e2e/background_image.spec.js @@ -0,0 +1,39 @@ +import { expect, test } from "@playwright/test"; + +const pagesWithSimpleImages = [ + { url: "/demos/background_images.html", description: "Background images" } +]; + +for (const { url, description } of pagesWithSimpleImages) { + test(description, async ({ page }) => { + await page.goto(url); + const lazyElements = await page.locator(".lazy"); + await page.waitForLoadState("load"); + const elementsCount = await lazyElements.count(); + + const devicePixelRatio = await page.evaluate(() => window.devicePixelRatio); + + // Eventually scroll into view and check if it loads + for (let i = 0; i < elementsCount; i++) { + const element = lazyElements.nth(i); + await element.scrollIntoViewIfNeeded(); + + // Set expectations + const dataBg = await element.getAttribute("data-bg"); + const dataBgHidpi = await element.getAttribute("data-bg-hidpi"); + const expectedBg = `background-image: url("${dataBg}");`; + const expectedHiDpiBg = `background-image: url("${dataBgHidpi}");`; + + if (!dataBgHidpi) { + await expect(element).toHaveAttribute("style", expectedBg); + continue; + } + + if (devicePixelRatio > 1) { + await expect(element).toHaveAttribute("style", expectedHiDpiBg); + } else { + await expect(element).toHaveAttribute("style", expectedBg); + } + } + }); +} diff --git a/tests/e2e/background_image_multi.spec.js b/tests/e2e/background_image_multi.spec.js new file mode 100644 index 00000000..4c56c5ec --- /dev/null +++ b/tests/e2e/background_image_multi.spec.js @@ -0,0 +1,39 @@ +import { expect, test } from "@playwright/test"; + +const pagesWithSimpleImages = [ + { url: "/demos/background_images_multi.html", description: "Multiple background images" } +]; + +for (const { url, description } of pagesWithSimpleImages) { + test(description, async ({ page }) => { + await page.goto(url); + const lazyElements = await page.locator(".lazy"); + await page.waitForLoadState("load"); + const elementsCount = await lazyElements.count(); + + const devicePixelRatio = await page.evaluate(() => window.devicePixelRatio); + + // Eventually scroll into view and check if it loads + for (let i = 0; i < elementsCount; i++) { + const element = lazyElements.nth(i); + await element.scrollIntoViewIfNeeded(); + + // Set expectations + const dataBgMulti = await element.getAttribute("data-bg-multi"); + const dataBgMultiHidpi = await element.getAttribute("data-bg-multi-hidpi"); + const expectedBg = `background-image: ${dataBgMulti};`; + const expectedHiDpiBg = `background-image: ${dataBgMultiHidpi};`; + + if (!dataBgMultiHidpi) { + await expect(element).toHaveAttribute("style", expectedBg); + continue; + } + + if (devicePixelRatio > 1) { + await expect(element).toHaveAttribute("style", expectedHiDpiBg); + } else { + await expect(element).toHaveAttribute("style", expectedBg); + } + } + }); +} diff --git a/tests/e2e/image_basic.spec.js b/tests/e2e/image_basic.spec.js new file mode 100644 index 00000000..5b23bf63 --- /dev/null +++ b/tests/e2e/image_basic.spec.js @@ -0,0 +1,26 @@ +import { expect, test } from "@playwright/test"; + +const pagesWithSimpleImages = [ + { url: "/demos/image_basic.html", description: "Basic page" }, + { url: "/demos/async.html", description: "Async initialization" }, + { url: "/demos/async_multiple.html", description: "Async initialization - multiple instances" }, +]; + +for (const { url, description } of pagesWithSimpleImages) { + test(description, async ({ page }) => { + await page.goto(url); + const lazyImages = await page.locator(".lazy"); + await page.waitForLoadState("load"); + const imageCount = await lazyImages.count(); + + // Eventually scroll into view and check if it loads + for (let i = 0; i < imageCount; i++) { + const image = lazyImages.nth(i); + await image.scrollIntoViewIfNeeded(); + + // Check the src attribute + const expectedSrc = await image.getAttribute("data-src"); + await expect(image).toHaveAttribute("src", expectedSrc); + } + }); +} diff --git a/src/__tests__/cancelOnExit.test.js b/tests/unit/cancelOnExit.test.js similarity index 85% rename from src/__tests__/cancelOnExit.test.js rename to tests/unit/cancelOnExit.test.js index c6335ba9..2b2ea4c0 100644 --- a/src/__tests__/cancelOnExit.test.js +++ b/tests/unit/cancelOnExit.test.js @@ -1,11 +1,12 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; +import { expect, beforeEach, afterEach, describe, test } from "@jest/globals"; -import { cancelLoading } from "../cancelOnExit"; -import { getExtendedSettings } from "../defaults"; -import { getStatus, setStatus } from "../data"; -import { statusLoaded } from "../elementStatus"; -import { setSources } from "../set"; +import { cancelLoading } from "../../src/cancelOnExit"; +import { getExtendedSettings } from "../../src/defaults"; +import { getStatus, setStatus } from "../../src/data"; +import { statusLoaded } from "../../src/elementStatus"; +import { setSources } from "../../src/set"; expectExtend(expect); @@ -46,7 +47,7 @@ describe("Cancel loading on img", () => { img.setAttribute("data-src", url200); setSources(img, settings); cancelLoading(img, entry, settings, instance); - expect(img).toHaveAttributeValue("src", url200); + expect(img).toHaveAttribute("src", url200); }); test("Does nothing if element is not loading", () => { @@ -54,7 +55,7 @@ describe("Cancel loading on img", () => { setSources(img, settings); setStatus(img, statusLoaded); cancelLoading(img, entry, settings, instance); - expect(img).toHaveAttributeValue("src", url200); + expect(img).toHaveAttribute("src", url200); }); test("Restores original attributes", () => { @@ -64,7 +65,7 @@ describe("Cancel loading on img", () => { img.setAttribute("data-sizes", sizes100); setSources(img, settings, instance); cancelLoading(img, entry, settings, instance); - expect(img).toHaveAttributeValue("src", url1); + expect(img).toHaveAttribute("src", url1); expect(img).not.toHaveAttribute("srcset"); expect(img).not.toHaveAttribute("sizes"); }); @@ -118,6 +119,6 @@ describe("Cancel loading on iframe", () => { iframe.setAttribute("data-src", iframeSrc); setSources(iframe, settings, instance); cancelLoading(iframe, entry, settings, instance); - expect(iframe).toHaveAttributeValue("src", iframeSrc); + expect(iframe).toHaveAttribute("src", iframeSrc); }); }); diff --git a/src/__tests__/lib/expectExtend.js b/tests/unit/lib/expectExtend.js similarity index 99% rename from src/__tests__/lib/expectExtend.js rename to tests/unit/lib/expectExtend.js index 3e2c6b19..c0f12b6b 100644 --- a/src/__tests__/lib/expectExtend.js +++ b/tests/unit/lib/expectExtend.js @@ -35,4 +35,4 @@ const extensions = { export default (expect) => { expect.extend(extensions); -}; \ No newline at end of file +}; diff --git a/src/__tests__/lib/getFakeInstance.js b/tests/unit/lib/getFakeInstance.js similarity index 100% rename from src/__tests__/lib/getFakeInstance.js rename to tests/unit/lib/getFakeInstance.js diff --git a/src/__tests__/load.test.js b/tests/unit/load.test.js similarity index 78% rename from src/__tests__/load.test.js rename to tests/unit/load.test.js index 6fcfcde9..c7a6ef65 100644 --- a/src/__tests__/load.test.js +++ b/tests/unit/load.test.js @@ -1,10 +1,11 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; +import { expect, beforeEach, afterEach, describe, test } from "@jest/globals"; -import { load } from "../load"; -import { getExtendedSettings } from "../defaults"; -import { getStatus } from "../data"; -import { statusLoading } from "../elementStatus"; +import { load } from "../../src/load"; +import { getExtendedSettings } from "../../src/defaults"; +import { getStatus } from "../../src/data"; +import { statusLoading } from "../../src/elementStatus"; expectExtend(expect); diff --git a/src/__tests__/originalAttributes.test.js b/tests/unit/originalAttributes.test.js similarity index 84% rename from src/__tests__/originalAttributes.test.js rename to tests/unit/originalAttributes.test.js index ef76f4a4..ca356650 100644 --- a/src/__tests__/originalAttributes.test.js +++ b/tests/unit/originalAttributes.test.js @@ -1,9 +1,10 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; -import { getExtendedSettings } from "../defaults"; +import { getExtendedSettings } from "../../src/defaults"; +import { expect, beforeEach, afterEach, describe, test } from "@jest/globals"; -import { setSources } from "../set"; -import { getOriginalAttrs } from "../originalAttributes"; +import { setSources } from "../../src/set"; +import { getOriginalAttrs } from "../../src/originalAttributes"; expectExtend(expect); diff --git a/src/__tests__/reset.test.js b/tests/unit/reset.test.js similarity index 84% rename from src/__tests__/reset.test.js rename to tests/unit/reset.test.js index ba9f7cd4..dc2646bc 100644 --- a/src/__tests__/reset.test.js +++ b/tests/unit/reset.test.js @@ -1,8 +1,9 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; -import { getExtendedSettings } from "../defaults"; +import { getExtendedSettings } from "../../src/defaults"; +import { expect, beforeEach, afterEach, describe, test } from "@jest/globals"; -import { resetSourcesImg } from "../reset"; +import { resetSourcesImg } from "../../src/reset"; expectExtend(expect); diff --git a/src/__tests__/restore.test.js b/tests/unit/restore.test.js similarity index 97% rename from src/__tests__/restore.test.js rename to tests/unit/restore.test.js index 26c36621..537c4e25 100644 --- a/src/__tests__/restore.test.js +++ b/tests/unit/restore.test.js @@ -1,9 +1,10 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; -import { getExtendedSettings } from "../defaults"; -import { restore } from "../restore"; -import { load } from "../load"; -import { getStatus } from "../data"; +import { beforeEach, afterEach, describe, expect, test } from "@jest/globals"; +import { getExtendedSettings } from "../../src/defaults"; +import { restore } from "../../src/restore"; +import { load } from "../../src/load"; +import { getStatus } from "../../src/data"; const url1 = "1.gif"; const url2 = "2.gif"; diff --git a/src/__tests__/set.test.js b/tests/unit/set.test.js similarity index 82% rename from src/__tests__/set.test.js rename to tests/unit/set.test.js index 0e3fbe12..776d5d5e 100644 --- a/src/__tests__/set.test.js +++ b/tests/unit/set.test.js @@ -1,8 +1,10 @@ import expectExtend from "./lib/expectExtend"; import getFakeInstance from "./lib/getFakeInstance"; -import { getExtendedSettings } from "../defaults"; +import { getExtendedSettings } from "../../src/defaults"; +import { expect, beforeEach, afterEach, describe, test } from "@jest/globals"; -import { setBackground, setMultiBackground, setSources } from "../set"; +import { setBackground, setMultiBackground, setSources } from "../../src/set"; +import { decreaseToLoadCount, setToLoadCount } from "../../src/counters"; expectExtend(expect); @@ -20,6 +22,20 @@ afterEach(() => { instance = null; }); +describe("setCounters", () => { + test('decreaseToLoadCount decreases toLoadCount by 1', () => { + const mockInstance = { toLoadCount: 5 }; + decreaseToLoadCount(mockInstance); + expect(mockInstance.toLoadCount).toBe(4); + }); + + test('setToLoadCount sets toLoadCount to the given value', () => { + const mockInstance = {}; + setToLoadCount(mockInstance, 10); + expect(mockInstance.toLoadCount).toBe(10); + }); +}) + describe("setSources for image", () => { let img; const url1 = "1.gif"; @@ -39,8 +55,8 @@ describe("setSources for image", () => { img.setAttribute("data-src", url200); img.setAttribute("data-srcset", url400); setSources(img, settings, instance); - expect(img).toHaveAttributeValue("src", url200); - expect(img).toHaveAttributeValue("srcset", url400); + expect(img).toHaveAttribute("src", url200); + expect(img).toHaveAttribute("srcset", url400); }); test("with initial values in src and srcset", () => { @@ -49,8 +65,8 @@ describe("setSources for image", () => { img.setAttribute("src", url1); img.setAttribute("srcset", url1); setSources(img, settings, instance); - expect(img).toHaveAttributeValue("src", url200); - expect(img).toHaveAttributeValue("srcset", url400); + expect(img).toHaveAttribute("src", url200); + expect(img).toHaveAttribute("srcset", url400); }); test("with initial values in src and srcset and empty data-*", () => { img.setAttribute("data-src", ""); @@ -58,8 +74,8 @@ describe("setSources for image", () => { img.setAttribute("src", url200); img.setAttribute("srcset", url400); setSources(img, settings, instance); - expect(img).toHaveAttributeValue("src", url200); - expect(img).toHaveAttributeValue("srcset", url400); + expect(img).toHaveAttribute("src", url200); + expect(img).toHaveAttribute("srcset", url400); }); }); @@ -80,19 +96,19 @@ describe("setSources for iframe", () => { test("with initially empty src", () => { iframe.setAttribute("data-src", srcToLoad); setSources(iframe, settings, instance); - expect(iframe).toHaveAttributeValue("src", srcToLoad); + expect(iframe).toHaveAttribute("src", srcToLoad); }); test("with initial value in src", () => { iframe.setAttribute("data-src", srcToLoad); iframe.setAttribute("src", preloadedSrc); setSources(iframe, settings, instance); - expect(iframe).toHaveAttributeValue("src", srcToLoad); + expect(iframe).toHaveAttribute("src", srcToLoad); }); test("with initial value in src and empty data-src", () => { iframe.setAttribute("data-src", ""); iframe.setAttribute("src", preloadedSrc); setSources(iframe, settings, instance); - expect(iframe).toHaveAttributeValue("src", preloadedSrc); + expect(iframe).toHaveAttribute("src", preloadedSrc); }); }); @@ -202,7 +218,7 @@ describe("setSources for video", () => { video.load = jest.fn(); video.setAttribute("data-src", videoUrlAvi); setSources(video, settings, instance); - expect(video).toHaveAttributeValue("src", videoUrlAvi); + expect(video).toHaveAttribute("src", videoUrlAvi); expect(video.load).toHaveBeenCalled(); }); @@ -214,9 +230,9 @@ describe("setSources for video", () => { source1.setAttribute("data-src", videoUrlMp4); source2.setAttribute("data-src", videoUrlWebm); setSources(video, settings, instance); - expect(video).toHaveAttributeValue("src", videoUrlAvi); - expect(source1).toHaveAttributeValue("src", videoUrlMp4); - expect(source2).toHaveAttributeValue("src", videoUrlWebm); + expect(video).toHaveAttribute("src", videoUrlAvi); + expect(source1).toHaveAttribute("src", videoUrlMp4); + expect(source2).toHaveAttribute("src", videoUrlWebm); expect(video.load).toHaveBeenCalled(); }); }); @@ -246,8 +262,8 @@ describe("setSources for picture", () => { source1.setAttribute("data-srcset", url200); source2.setAttribute("data-srcset", url400); setSources(img, settings, instance); - expect(source1).toHaveAttributeValue("srcset", url200); - expect(source2).toHaveAttributeValue("srcset", url400); + expect(source1).toHaveAttribute("srcset", url200); + expect(source2).toHaveAttribute("srcset", url400); }); test("with initial value in srcset", () => { @@ -256,8 +272,8 @@ describe("setSources for picture", () => { source1.setAttribute("srcset", url1); source2.setAttribute("srcset", url1); setSources(img, settings, instance); - expect(source1).toHaveAttributeValue("srcset", url200); - expect(source2).toHaveAttributeValue("srcset", url400); + expect(source1).toHaveAttribute("srcset", url200); + expect(source2).toHaveAttribute("srcset", url400); }); test("with initial value in srcset and empty data-srcset", () => { @@ -266,7 +282,7 @@ describe("setSources for picture", () => { source1.setAttribute("srcset", url200); source2.setAttribute("srcset", url400); setSources(img, settings, instance); - expect(source1).toHaveAttributeValue("srcset", url200); - expect(source2).toHaveAttributeValue("srcset", url400); + expect(source1).toHaveAttribute("srcset", url200); + expect(source2).toHaveAttribute("srcset", url400); }); }); diff --git a/todo.md b/todo.md index 2fb4f779..2892a343 100644 --- a/todo.md +++ b/todo.md @@ -1,6 +1,23 @@ # TODO -## Coming next +## 1 + +Remove temporary fix from `./src/set.js` + +```js +// Temporary fix for Chromeium with the -webkit- prefix +if (element.style.backgroundImage === "") { + bgImageValues = imgSetValues.map((value) => `-webkit-image-set(${value})`); + element.style.backgroundImage = bgImageValues.join(); +} +``` + +## 2 + +Check why the demo `./demos/restore_destroy.html` is not working. What was it supposed to do? :D + + +## To consider - Check how LazyLoad behaves when a page was updated using DOM morphing. If only the data-attributes were updated, how do one forces LazyLoad to read from them again? @@ -8,13 +25,10 @@ - Consider creating a subset of options and defaults for the static `load` method, and document it - [Edge case] When `cancel_on_exit` is `false`, unobserve elements as soon as they start loading (as of before 15.2.0). -## Test - -- Test more modules and functions, coverage!!! -- Test native `img`, native `iframe`, alone or in conjunction with `video`s. +## More tests -Test more modules +Add more tests (to choose between unit tests or e2e tests depending on the case) to cover: -- [ ] autoinitialize -- [ ] purge -- [ ] reveal +- autoinitialize +- purge +- reveal \ No newline at end of file diff --git a/utils/index.html b/utils/index.html new file mode 100644 index 00000000..374064df --- /dev/null +++ b/utils/index.html @@ -0,0 +1,444 @@ + + + + + Self-host images generator + + + + + +

    Self-host images generator

    +
    +
      +
    • + Stivaletti +
    • +
    • + Open toe +
    • +
    • + Sneakers & Tennis +
    • +
    • + Sneakers & Tennis shoes basse +
    • +
    • + Sneakers & Tennis shoes alte +
    • +
    • + Sneakers & Tennis shoes alte +
    • +
    • + Sneakers & Tennis shoes basse +
    • +
    • + Sneakers & Tennis shoes basse +
    • +
    • + Stivali +
    • +
    • + Stivali +
    • +
    • + Stivaletti +
    • +
    • + Stivaletti +
    • +
    • + Stivali +
    • +
    • + Stivaletti +
    • +
    • + DĂ©colletĂ© +
    • +
    • + Mocassini +
    • +
    • + Stivaletti +
    • +
    • + DĂ©colletĂ© +
    • +
    • + DĂ©colletĂ© +
    • +
    • + Francesine +
    • +
    • + Stivaletti +
    • +
    • + DĂ©colletĂ© +
    • +
    • + Mocassini +
    • +
    • + Mocassini +
    • +
    • + Stivali +
    • +
    • + Stivaletti +
    • +
    • + Stivaletti +
    • +
    • + Mocassini +
    • +
    • + Stivaletti +
    • +
    • + Stivaletti +
    • +
    • + Stivaletti +
    • +
    • + Stivaletti +
    • +
    • + Cuissardes +
    • +
    • + DĂ©colletĂ© +
    • +
    • + Stivaletti +
    • +
    • + Sneakers & Tennis shoes basse +
    • +
    • + Mocassini +
    • +
    • + Sneakers & Tennis shoes basse +
    • +
    • + Mocassini +
    • +
    • + Mocassini +
    • +
    +
    + +