diff --git a/.github/workflows/functional_all_db.yml b/.github/workflows/functional_all_db.yml index b19b40a8252..3458afea946 100644 --- a/.github/workflows/functional_all_db.yml +++ b/.github/workflows/functional_all_db.yml @@ -17,6 +17,8 @@ on: env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: true + PLAYWRIGHT_TRACING: true + ASPNETCORE_ENVIRONMENT: Production jobs: test_functional_mvc: @@ -30,27 +32,32 @@ jobs: github.event.review.state == 'APPROVED' || github.event.review.state == 'CHANGES_REQUESTED' runs-on: ubuntu-24.04 - container: - image: cypress/included:15.12.0 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup-dotnet - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - name: Build + run: | + dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj + - name: Cache Playwright Browsers + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: - node-version: "15" - package-manager-cache: false + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium - name: Functional Tests run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run mvc:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: - name: functional-mvc-screenshots - path: test/OrchardCore.Tests.Functional/mvc-tests/cypress/screenshots + name: functional-mvc-failure + path: | + src/OrchardCore.Mvc.Web/App_Data_Tests/logs + test/OrchardCore.Tests.Functional/traces retention-days: 3 - + test_functional_cms_sqlite: name: Functional Tests - CMS Sqlite if: github.event_name == 'workflow_dispatch' || @@ -58,25 +65,32 @@ jobs: github.event.review.state == 'APPROVED' || github.event.review.state == 'CHANGES_REQUESTED' runs-on: ubuntu-24.04 - container: - image: cypress/included:15.12.0 env: OrchardCore__OrchardCore_YesSql__EnableThreadSafetyChecks: true steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup-dotnet + - name: Build + run: | + dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj + - name: Cache Playwright Browsers + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium - name: Functional Tests run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: name: functional-cms-sqlite-failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + test/OrchardCore.Tests.Functional/traces retention-days: 3 test_functional_cms_postgresql: @@ -86,11 +100,14 @@ jobs: github.event.review.state == 'APPROVED' || github.event.review.state == 'CHANGES_REQUESTED' runs-on: ubuntu-24.04 - container: - image: cypress/included:15.12.0 services: postgres: image: postgres:11 + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + ports: + - 5432:5432 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: admin @@ -102,24 +119,33 @@ jobs: --health-timeout 5s --health-retries 5 env: - OrchardCore__ConnectionString: "User ID=postgres;Password=admin;Host=postgres;Port=5432;Database=app;" + OrchardCore__ConnectionString: "User ID=postgres;Password=admin;Host=localhost;Port=5432;Database=app;" OrchardCore__DatabaseProvider: "Postgres" OrchardCore__OrchardCore_YesSql__EnableThreadSafetyChecks: true steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup-dotnet + - name: Build + run: | + dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj + - name: Cache Playwright Browsers + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium - name: Functional Tests run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: name: functional-cms-postgresql-failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + test/OrchardCore.Tests.Functional/traces retention-days: 3 test_functional_cms_mysql: @@ -129,36 +155,46 @@ jobs: github.event.review.state == 'APPROVED' || github.event.review.state == 'CHANGES_REQUESTED' runs-on: ubuntu-24.04 - container: - image: cypress/included:15.12.0 services: mysql: image: mysql:8 + credentials: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} ports: - - 3306 + - 3306:3306 env: MYSQL_DATABASE: test MYSQL_ROOT_PASSWORD: test123 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 env: - OrchardCore__ConnectionString: "server=mysql;uid=root;pwd=test123;database=test" + OrchardCore__ConnectionString: "server=localhost;uid=root;pwd=test123;database=test" OrchardCore__DatabaseProvider: "MySql" OrchardCore__OrchardCore_YesSql__EnableThreadSafetyChecks: true steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup-dotnet + - name: Build + run: | + dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj + - name: Cache Playwright Browsers + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium - name: Functional Tests run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: name: functional-cms-mysql-failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + test/OrchardCore.Tests.Functional/traces retention-days: 3 test_functional_cms_mssql: @@ -168,33 +204,40 @@ jobs: github.event.review.state == 'APPROVED' || github.event.review.state == 'CHANGES_REQUESTED' runs-on: ubuntu-24.04 - container: - image: cypress/included:15.12.0 services: mssql: image: mcr.microsoft.com/mssql/server:2019-latest ports: - - 1433 + - 1433:1433 env: ACCEPT_EULA: Y MSSQL_SA_PASSWORD: Password12! env: - OrchardCore__ConnectionString: "Server=mssql;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False" + OrchardCore__ConnectionString: "Server=localhost;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False" OrchardCore__DatabaseProvider: "SqlConnection" OrchardCore__OrchardCore_YesSql__EnableThreadSafetyChecks: true steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/setup-dotnet + - name: Build + run: | + dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj + - name: Cache Playwright Browsers + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium - name: Functional Tests run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: name: functional-cms-mssql-failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + test/OrchardCore.Tests.Functional/traces retention-days: 3 diff --git a/.github/workflows/main_ci.yml b/.github/workflows/main_ci.yml index 99decdfcc51..1f8a01d74cb 100644 --- a/.github/workflows/main_ci.yml +++ b/.github/workflows/main_ci.yml @@ -13,6 +13,7 @@ on: env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: true + PLAYWRIGHT_TRACING: true jobs: test: @@ -24,10 +25,6 @@ jobs: os: [ubuntu-24.04, windows-2022] steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version: "15" - package-manager-cache: false - uses: ./.github/actions/setup-dotnet - name: Build # See pr_ci.yml for the reason why we disable NuGet audit warnings. @@ -36,17 +33,30 @@ jobs: - name: Unit Tests run: | dotnet test --project ./test/OrchardCore.Tests/OrchardCore.Tests.csproj -c Release --no-build - - name: Functional Tests + - name: Cache Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + - name: Functional Tests - CMS + if: matrix.os == 'ubuntu-24.04' + run: | + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" + - name: Functional Tests - MVC if: matrix.os == 'ubuntu-24.04' run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test - npm run mvc:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: matrix.os == 'ubuntu-24.04' && failure() with: name: Functional Test failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data_Tests/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + src/OrchardCore.Mvc.Web/App_Data_Tests/logs + test/OrchardCore.Tests.Functional/traces + retention-days: 3 diff --git a/.github/workflows/pr_ci.yml b/.github/workflows/pr_ci.yml index 909b05184d1..a81206a5af5 100644 --- a/.github/workflows/pr_ci.yml +++ b/.github/workflows/pr_ci.yml @@ -8,6 +8,7 @@ concurrency: env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: true + PLAYWRIGHT_TRACING: true jobs: build_test: runs-on: ${{ matrix.os }} @@ -18,10 +19,6 @@ jobs: name: Build & Test steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version: "15" - package-manager-cache: false - uses: ./.github/actions/setup-dotnet - name: Build # We disable NuGet audit warnings, see https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1901-nu1904. @@ -33,17 +30,30 @@ jobs: - name: Unit Tests run: | dotnet test --project ./test/OrchardCore.Tests/OrchardCore.Tests.csproj -c Release --no-build - - name: Functional Tests + - name: Cache Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + - name: Functional Tests - CMS + if: matrix.os == 'ubuntu-24.04' + run: | + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" + - name: Functional Tests - MVC if: matrix.os == 'ubuntu-24.04' run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test - npm run mvc:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: matrix.os == 'ubuntu-24.04' && failure() with: name: functional-test-failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + src/OrchardCore.Mvc.Web/App_Data_Tests/logs + test/OrchardCore.Tests.Functional/traces + retention-days: 3 diff --git a/.github/workflows/preview_ci.yml b/.github/workflows/preview_ci.yml index e2e251de184..63e09f26b38 100644 --- a/.github/workflows/preview_ci.yml +++ b/.github/workflows/preview_ci.yml @@ -23,11 +23,6 @@ jobs: Write-Output "Commits found in the last 24 hours: $hasCommitFromLastDay." $shouldPublish = ($hasCommitFromLastDay -and '${{ github.event_name }}' -eq 'schedule') -or ('${{ github.event_name }}' -eq 'workflow_dispatch') "should-publish=$($shouldPublish ? 'true' : 'false')" >> $Env:GITHUB_OUTPUT - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - if: steps.check-publish.outputs.should-publish == 'true' - with: - node-version: "15" - package-manager-cache: false - uses: ./.github/actions/setup-dotnet if: steps.check-publish.outputs.should-publish == 'true' - name: Set build number @@ -42,20 +37,33 @@ jobs: if: steps.check-publish.outputs.should-publish == 'true' run: | dotnet test --project ./test/OrchardCore.Tests/OrchardCore.Tests.csproj -c Release --no-build - - name: Functional Tests + - name: Cache Playwright Browsers + if: steps.check-publish.outputs.should-publish == 'true' + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + if: steps.check-publish.outputs.should-publish == 'true' + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + - name: Functional Tests - CMS + if: steps.check-publish.outputs.should-publish == 'true' + run: | + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" + - name: Functional Tests - MVC if: steps.check-publish.outputs.should-publish == 'true' run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test - npm run mvc:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: failure() with: name: Functional Test failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data_Tests/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + src/OrchardCore.Mvc.Web/App_Data_Tests/logs + test/OrchardCore.Tests.Functional/traces + retention-days: 3 - name: Deploy preview NuGet packages if: steps.check-publish.outputs.should-publish == 'true' run: | @@ -75,7 +83,7 @@ jobs: shell: pwsh run: | Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data -Recurse | Remove-Item -Recurse -Confirm:$false - Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data_Tests -Recurse | Remove-Item -Recurse -Confirm:$false + Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data_Tests_* -Recurse | Remove-Item -Recurse -Confirm:$false $output = [System.IO.Path]::GetFullPath("./.build/release") dotnet publish src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj -c Release --property:PublishDir=$output --no-build --framework net10.0 docker buildx build -f Dockerfile-CI --platform=linux/amd64 -t orchardproject/orchardcore-cms-linux:dev --push . diff --git a/.github/workflows/release_ci.yml b/.github/workflows/release_ci.yml index b354c6dbf59..62f142dd0e1 100644 --- a/.github/workflows/release_ci.yml +++ b/.github/workflows/release_ci.yml @@ -28,10 +28,6 @@ jobs: echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT shell: bash - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 - with: - node-version: "15" - package-manager-cache: false - uses: ./.github/actions/setup-dotnet - name: Set build number if: matrix.os == 'ubuntu-24.04' @@ -44,20 +40,33 @@ jobs: - name: Unit Tests run: | dotnet test --project ./test/OrchardCore.Tests/OrchardCore.Tests.csproj -c Release --no-build - - name: Functional Tests + - name: Cache Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ hashFiles('Directory.Packages.props') }} + - name: Install Playwright Browsers + if: matrix.os == 'ubuntu-24.04' + run: | + pwsh test/OrchardCore.Tests.Functional/bin/Release/net10.0/playwright.ps1 install --with-deps chromium + - name: Functional Tests - CMS + if: matrix.os == 'ubuntu-24.04' + run: | + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" + - name: Functional Tests - MVC if: matrix.os == 'ubuntu-24.04' run: | - cd test/OrchardCore.Tests.Functional - npm install - npm run cms:test - npm run mvc:test + dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: matrix.os == 'ubuntu-24.04' && failure() with: name: Functional Test failure path: | - test/OrchardCore.Tests.Functional/cms-tests/cypress/screenshots - src/OrchardCore.Cms.Web/App_Data_Tests/logs + src/OrchardCore.Cms.Web/App_Data_Tests_*/logs + src/OrchardCore.Mvc.Web/App_Data_Tests/logs + test/OrchardCore.Tests.Functional/traces + retention-days: 3 - name: Deploy release NuGet packages if: matrix.os == 'ubuntu-24.04' run: | @@ -77,7 +86,7 @@ jobs: shell: pwsh run: | Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data -Recurse | Remove-Item -Recurse -Confirm:$false - Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data_Tests -Recurse | Remove-Item -Recurse -Confirm:$false + Get-ChildItem ./src/OrchardCore.Cms.Web/App_Data_Tests_* -Recurse | Remove-Item -Recurse -Confirm:$false $output = [System.IO.Path]::GetFullPath("./.build/release") dotnet publish src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj -c Release --property:PublishDir=$output --no-build --framework net10.0 docker buildx build -f Dockerfile-CI --platform=linux/amd64 -t orchardproject/orchardcore-cms-linux:latest -t orchardproject/orchardcore-cms-linux:${{ steps.get_version.outputs.VERSION }} --push . diff --git a/AGENTS.md b/AGENTS.md index 214100ef8c0..af8401b0340 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -96,14 +96,16 @@ of each filter. This is categorized as a simple filter. You cannot use both simple filters and query filters. -### Functional Tests (Cypress) +### Functional Tests (Playwright) End-to-end tests are located in `test/OrchardCore.Tests.Functional/`. ```bash -cd test/OrchardCore.Tests.Functional -npm install -npm run cms:test +# Run CMS functional tests +dotnet test test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj --filter-class "*Cms*" + +# Run MVC functional tests +dotnet test test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj --filter-class "*Mvc*" ``` ### Automated Browser Testing (Playwright MCP) @@ -128,7 +130,7 @@ For AI agents, the Playwright MCP (Model Context Protocol) provides automated br - `test/OrchardCore.Tests/` - Main unit test project - `test/OrchardCore.Abstractions.Tests/` - Tests for abstractions -- `test/OrchardCore.Tests.Functional/` - Cypress E2E tests +- `test/OrchardCore.Tests.Functional/` - Playwright E2E functional tests - `test/OrchardCore.Tests.Modules/` - Test modules used by tests ## Project Structure @@ -373,20 +375,18 @@ Stop-Process -Id (Get-Content .orchardcore-pid) -Force; Remove-Item .orchardcore **Debugging**: Check `src/OrchardCore.Cms.Web/App_Data/logs/orchard-log-{date}.log` -### Functional Testing with Cypress +### Functional Testing with Playwright -Create new functional tests under `test/OrchardCore.Tests.Functional/cypress/` following the existing spec patterns. +Create new functional tests under `test/OrchardCore.Tests.Functional/Tests/` following the existing C# test class patterns. -Run the Cypress functional tests: +Run the Playwright functional tests: ```bash -cd test/OrchardCore.Tests.Functional - -# Required before first usage -npm install +# Run CMS functional tests +dotnet test test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj --filter-class "*Cms*" -# Run all functional tests -npm run cms:test +# Run MVC functional tests +dotnet test test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj --filter-class "*Mvc*" ``` ## Common Extension Points diff --git a/Directory.Packages.props b/Directory.Packages.props index f55920eaa08..82997b76e9a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -97,10 +97,12 @@ + + diff --git a/OrchardCore.slnx b/OrchardCore.slnx index ddb4c52e87e..35c4caa50a1 100644 --- a/OrchardCore.slnx +++ b/OrchardCore.slnx @@ -288,8 +288,8 @@ - + diff --git a/src/docs/reference/libraries/README.md b/src/docs/reference/libraries/README.md index c2a86c15def..8a79ea0de69 100644 --- a/src/docs/reference/libraries/README.md +++ b/src/docs/reference/libraries/README.md @@ -96,8 +96,7 @@ The below table lists the different Tests libraries: | Library | Usage | License | |--- | --- | --- | | [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) | Powerful .NET library for benchmarking. | [MIT](https://github.com/dotnet/BenchmarkDotNet/blob/master/LICENSE.md) | -| [Cypress](https://github.com/cypress-io/cypress) | Fast, easy and reliable testing for anything that runs in a browser. | [MIT](https://github.com/cypress-io/cypress/blob/develop/LICENSE) | -| [Cypress Orchard](https://www.npmjs.com/package/cypress-orchardcore) | A collection of cypress commands for Orchard Core. | MIT | +| [Playwright](https://github.com/microsoft/playwright) | Reliable end-to-end testing for modern web apps. | [Apache-2.0](https://github.com/microsoft/playwright/blob/main/LICENSE) | | [Moq](https://github.com/moq/moq) | The most popular and friendly mocking framework for .NET. | [MIT](https://github.com/moq/moq/blob/main/LICENSE) | | [VS Test SDK](https://github.com/microsoft/vstest/) | Visual Studio Test Platform. | [MIT](https://github.com/microsoft/vstest/blob/master/LICENSE) | | [xUnit](https://github.com/xunit/xunit) | Free, open source, community-focused unit testing tool for the .NET Framework. | [MIT](https://github.com/xunit/xunit/blob/main/LICENSE) | diff --git a/test/OrchardCore.Tests.Functional/.gitignore b/test/OrchardCore.Tests.Functional/.gitignore deleted file mode 100644 index 82089668cdb..00000000000 --- a/test/OrchardCore.Tests.Functional/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -**/cypress/screenshots -**/cypress/videos diff --git a/test/OrchardCore.Tests.Functional/cms-tests/Recipes/migrations.recipe.json b/test/OrchardCore.Tests.Functional/Fixtures/migrations.recipe.json similarity index 100% rename from test/OrchardCore.Tests.Functional/cms-tests/Recipes/migrations.recipe.json rename to test/OrchardCore.Tests.Functional/Fixtures/migrations.recipe.json diff --git a/test/OrchardCore.Tests.Functional/Helpers/AuthHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/AuthHelper.cs new file mode 100644 index 00000000000..8ee0de205b3 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/AuthHelper.cs @@ -0,0 +1,23 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class AuthHelper +{ + public static async Task LoginAsync(this IPage page, string prefix = "", OrchardConfig config = null) + { + config ??= TestUtils.DefaultConfig; + await page.GotoAsync($"{prefix}/login"); + + // If already logged in (redirected away from login), skip. + if (!page.Url.Contains("/login", StringComparison.OrdinalIgnoreCase)) + { + return; + } + + await page.Locator("#LoginForm_UserName").FillAsync(config.Username); + await page.Locator("#LoginForm_Password").FillAsync(config.Password); + await page.Locator("button[type=\"submit\"]").ClickAsync(); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/ButtonHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/ButtonHelper.cs new file mode 100644 index 00000000000..f30ae603411 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/ButtonHelper.cs @@ -0,0 +1,27 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class ButtonHelper +{ + public static Task ClickCreateAsync(this IPage page) + => page.Locator(".btn.create").ClickAsync(); + + public static Task ClickSaveAsync(this IPage page) + => page.Locator(".btn.save").ClickAsync(); + + public static Task ClickSaveContinueAsync(this IPage page) + => page.Locator(".dropdown-item.save-continue").ClickAsync(); + + public static Task ClickCancelAsync(this IPage page) + => page.Locator(".btn.cancel").ClickAsync(); + + public static Task ClickPublishAsync(this IPage page) + => page.Locator(".btn.publish").ClickAsync(); + + public static Task ClickPublishContinueAsync(this IPage page) + => page.Locator(".dropdown-item.publish-continue").ClickAsync(); + + public static Task ClickModalOkAsync(this IPage page) + => page.Locator("#modalOkButton").ClickAsync(); +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/ConfigurationHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/ConfigurationHelper.cs new file mode 100644 index 00000000000..a529eec96c5 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/ConfigurationHelper.cs @@ -0,0 +1,15 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class ConfigurationHelper +{ + public static async Task SetPageSizeAsync(this IPage page, string prefix, string size) + { + await page.GotoAsync($"{prefix}/Admin/Settings/general"); + await page.Locator("#ISite_PageSize").ClearAsync(); + await page.Locator("#ISite_PageSize").FillAsync(size); + await page.ClickSaveAsync(); + await page.Locator(".message-success").WaitForAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/EmbeddedRecipeHarvester.cs b/test/OrchardCore.Tests.Functional/Helpers/EmbeddedRecipeHarvester.cs new file mode 100644 index 00000000000..7a6335f2e84 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/EmbeddedRecipeHarvester.cs @@ -0,0 +1,72 @@ +using Microsoft.Extensions.FileProviders; +using OrchardCore.Recipes.Models; +using OrchardCore.Recipes.Services; + +namespace OrchardCore.Tests.Functional.Helpers; + +/// +/// Serves recipes embedded in the test assembly, eliminating the need to copy +/// recipe files to the application's Recipes folder at runtime. +/// +public sealed class EmbeddedRecipeHarvester : IRecipeHarvester +{ + private readonly IRecipeReader _recipeReader; + private readonly EmbeddedFileProvider _fileProvider; + + public EmbeddedRecipeHarvester(IRecipeReader recipeReader) + { + _recipeReader = recipeReader; + _fileProvider = new EmbeddedFileProvider(typeof(EmbeddedRecipeHarvester).Assembly); + } + + public async Task> HarvestRecipesAsync() + { + var recipes = new List(); + var assembly = typeof(EmbeddedRecipeHarvester).Assembly; + var assemblyPrefix = assembly.GetName().Name + "."; + + foreach (var resourceName in assembly.GetManifestResourceNames() + .Where(n => n.EndsWith(".recipe.json", StringComparison.OrdinalIgnoreCase))) + { + string subpath; + if (resourceName.StartsWith(assemblyPrefix, StringComparison.Ordinal)) + { + // Trim the assembly name prefix to get a name relative to the provider base namespace. + var trimmed = resourceName.Substring(assemblyPrefix.Length); + + // Convert the first namespace separator to a path separator (e.g. "Recipes.Foo.recipe.json" -> "Recipes/Foo.recipe.json"), + // which matches the subpath format expected by EmbeddedFileProvider. + var firstDotIndex = trimmed.IndexOf('.'); + if (firstDotIndex >= 0) + { + subpath = string.Concat(trimmed.AsSpan(0, firstDotIndex), "/", trimmed.AsSpan(firstDotIndex + 1)); + } + else + { + subpath = trimmed; + } + } + else + { + // Fallback: use the resource name as-is if it does not start with the assembly prefix. + subpath = resourceName; + } + + var fileInfo = _fileProvider.GetFileInfo(subpath); + if (!fileInfo.Exists) + { + continue; + } + + var descriptor = await _recipeReader.GetRecipeDescriptorAsync( + string.Empty, fileInfo, _fileProvider); + + if (descriptor is not null) + { + recipes.Add(descriptor); + } + } + + return recipes; + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/FeatureHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/FeatureHelper.cs new file mode 100644 index 00000000000..6ebaa3be278 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/FeatureHelper.cs @@ -0,0 +1,18 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class FeatureHelper +{ + public static async Task EnableFeatureAsync(this IPage page, string prefix, string featureName) + { + await page.GotoAsync($"{prefix}/Admin/Features"); + await page.Locator($"#btn-enable-{featureName}").ClickAsync(); + } + + public static async Task DisableFeatureAsync(this IPage page, string prefix, string featureName) + { + await page.GotoAsync($"{prefix}/Admin/Features"); + await page.Locator($"#btn-disable-{featureName}").ClickAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/OrchardTestFixture.cs b/test/OrchardCore.Tests.Functional/Helpers/OrchardTestFixture.cs new file mode 100644 index 00000000000..46b953a3eba --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/OrchardTestFixture.cs @@ -0,0 +1,169 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public sealed class OrchardTestFixture : IAsyncDisposable +{ + private static int _traceCounter; + + private static readonly bool _tracingEnabled = + !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("PLAYWRIGHT_TRACING")); + + private static readonly string _traceDir = + Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "traces"); + + private readonly bool _isMvc; + private readonly string _instanceId; + + private OrchardTestServer _server; + private IPlaywright _playwright; + private IBrowser _browser; + private bool _disposed; + + public string BaseUrl { get; private set; } + public IBrowser Browser => _browser; + + public OrchardTestFixture(bool isMvc = false, string instanceId = null) + { + _isMvc = isMvc; + _instanceId = instanceId; + } + + private static string ProjectRoot => + Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..")); + + private string AppDir => + _isMvc + ? Path.Combine(ProjectRoot, "src", "OrchardCore.Mvc.Web") + : Path.Combine(ProjectRoot, "src", "OrchardCore.Cms.Web"); + + private string AppDataPath => + string.IsNullOrEmpty(_instanceId) + ? Path.Combine(AppDir, "App_Data_Tests") + : Path.Combine(AppDir, $"App_Data_Tests_{_instanceId}"); + + public async Task InitializeAsync() + { + // Clean previous test data. + if (Directory.Exists(AppDataPath)) + { + Directory.Delete(AppDataPath, recursive: true); + } + + if (string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("ORCHARD_EXTERNAL"))) + { + _server = _isMvc + ? await OrchardTestServer.StartMvcAsync(AppDir, AppDataPath) + : await OrchardTestServer.StartCmsAsync(AppDir, AppDataPath, _instanceId); + + BaseUrl = _server.ServerAddress; + } + else + { + BaseUrl = System.Environment.GetEnvironmentVariable("ORCHARD_URL") + ?? "http://localhost:5000"; + } + + _playwright = await Playwright.CreateAsync(); + _browser = await _playwright.Chromium.LaunchAsync( + new BrowserTypeLaunchOptions { Headless = true } + ); + } + + public async Task CreatePageAsync(string traceName = null) + { + // Capture the test display name at call time (inside the test) so it can be used + // when the page close event fires (potentially after the test has completed). + var capturedTraceName = traceName ?? SanitizeFileName(TestContext.Current?.Test?.TestDisplayName); + + var context = await _browser.NewContextAsync( + new BrowserNewContextOptions { BaseURL = BaseUrl } + ); + + if (_tracingEnabled) + { + await context.Tracing.StartAsync(new TracingStartOptions + { + Screenshots = true, + Snapshots = true, + Sources = true, + }); + } + + var page = await context.NewPageAsync(); + + page.Close += async (_, _) => + { + try + { + if (_tracingEnabled) + { + var traceIndex = Interlocked.Increment(ref _traceCounter); + var fileName = string.IsNullOrEmpty(capturedTraceName) + ? $"trace-{traceIndex}.zip" + : $"trace-{capturedTraceName}-{traceIndex}.zip"; + + Directory.CreateDirectory(_traceDir); + + await context.Tracing.StopAsync(new TracingStopOptions + { + Path = Path.Combine(_traceDir, fileName), + }); + } + + await context.CloseAsync(); + } + catch (Exception) + { + // Context may already be closed (e.g., when the browser is being disposed). + } + }; + + return page; + } + + private static string SanitizeFileName(string name) + { + if (string.IsNullOrEmpty(name)) + { + return null; + } + + var invalidChars = Path.GetInvalidFileNameChars(); + return string.Concat(name.Select(c => Array.IndexOf(invalidChars, c) >= 0 ? '_' : c)); + } + + public void AssertNoLoggedIssues() => _server?.AssertNoLoggedIssues(); + + public async ValueTask DisposeAsync() + { + if (_disposed) + { + return; + } + + _disposed = true; + + if (_browser is not null) + { + await _browser.CloseAsync(); + } + + _playwright?.Dispose(); + + if (_server is not null) + { + await _server.DisposeAsync(); + } + + if (Directory.Exists(AppDataPath)) + { + // Clear SQLite connection pool to release file locks before deleting. + global::Microsoft.Data.Sqlite.SqliteConnection.ClearPool( + new global::Microsoft.Data.Sqlite.SqliteConnection( + $"Data Source={Path.Combine(AppDataPath, "Sites", "Default", "yessql.db")}")); + + Directory.Delete(AppDataPath, recursive: true); + } + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/OrchardTestServer.cs b/test/OrchardCore.Tests.Functional/Helpers/OrchardTestServer.cs new file mode 100644 index 00000000000..4c807d4f992 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/OrchardTestServer.cs @@ -0,0 +1,350 @@ +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using OrchardCore.Environment.Shell; +using OrchardCore.Logging; +using OrchardCore.Recipes.Services; + +namespace OrchardCore.Tests.Functional.Helpers; + +public sealed class OrchardTestServer : IAsyncDisposable +{ + // Capture the original values once at process start, then clear the env vars so + // ShellSettingsManager can't re-apply them with highest priority — each host gets + // its per-fixture connection string via tenants.json and builder.Configuration instead. + private static readonly string _originalConnectionString = CaptureAndClear("OrchardCore__ConnectionString"); + private static readonly string _originalDatabaseProvider = CaptureAndClear("OrchardCore__DatabaseProvider"); + + private static string CaptureAndClear(string variable) + { + var value = System.Environment.GetEnvironmentVariable(variable); + if (!string.IsNullOrEmpty(value)) + { + System.Environment.SetEnvironmentVariable(variable, null); + } + + return value; + } + + /// + /// The per-fixture connection string used by the most recently started server. + /// Used by test helpers (e.g., CreateTenantAsync) to fill in child tenant connection strings. + /// + [ThreadStatic] + private static string _currentConnectionString; + + public static string CurrentConnectionString => _currentConnectionString; + + private readonly WebApplication _app; + private readonly FakeLogCollector _logCollector; + + public string ServerAddress { get; } + + private OrchardTestServer(WebApplication app, string serverAddress, FakeLogCollector logCollector) + { + _app = app; + ServerAddress = serverAddress; + _logCollector = logCollector; + } + + public static async Task StartCmsAsync(string contentRoot, string appDataPath, string instanceId = null) + { + var loggerProvider = new FakeLoggerProvider(); + + var builder = WebApplication.CreateBuilder(new WebApplicationOptions + { + ApplicationName = "OrchardCore.Cms.Web", + ContentRootPath = contentRoot, + }); + + builder.Host.UseNLogHost(); + + builder.Services + .AddOrchardCms() + .AddSetupFeatures("OrchardCore.AutoSetup"); + + // Serve test recipes from embedded resources instead of copying files. + builder.Services.AddScoped(); + + ConfigureServices(builder, appDataPath, instanceId, loggerProvider); + + var app = builder.Build(); + app.UseStaticFiles(); + app.UseOrchardCore(); + + await app.StartAsync(); + + return new OrchardTestServer(app, GetListeningAddress(app), loggerProvider.Collector); + } + + public static async Task StartMvcAsync(string contentRoot, string appDataPath) + { + var loggerProvider = new FakeLoggerProvider(); + + var builder = WebApplication.CreateBuilder(new WebApplicationOptions + { + ApplicationName = "OrchardCore.Mvc.Web", + ContentRootPath = contentRoot, + }); + + builder.Services + .AddOrchardCore() + .AddMvc(); + + ConfigureServices(builder, appDataPath, instanceId: null, loggerProvider); + + var app = builder.Build(); + app.UseStaticFiles(); + app.UseOrchardCore(); + + await app.StartAsync(); + + return new OrchardTestServer(app, GetListeningAddress(app), loggerProvider.Collector); + } + + public void AssertNoLoggedIssues() + { + var issues = _logCollector.GetSnapshot() + .Where(e => e.Level >= LogLevel.Warning) + .Where(e => !IsIgnoredWarning(e)) + .ToList(); + + if (issues.Count > 0) + { + var messages = string.Join( + System.Environment.NewLine, + issues.Select(e => $"[{e.Level}] {e.Category}: {e.Message}{(e.Exception is not null ? $" -> {e.Exception}" : string.Empty)}")); + + throw new Xunit.Sdk.XunitException( + $"Expected no logged warnings or errors, but found {issues.Count}:{System.Environment.NewLine}{messages}"); + } + } + + private static bool IsIgnoredWarning(FakeLogRecord record) => + record.Category == "Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager" + && record.Message.Contains("No XML encryptor configured"); + + public async ValueTask DisposeAsync() + { + if (_app is not null) + { + await _app.StopAsync(); + await _app.DisposeAsync(); + } + } + + private static void ConfigureServices( + WebApplicationBuilder builder, + string appDataPath, + string instanceId, + FakeLoggerProvider loggerProvider) + { + builder.WebHost.UseUrls("http://127.0.0.1:0"); + builder.WebHost.UseSetting("suppressHostingStartup", "true"); + + var resolvedAppDataPath = Path.IsPathRooted(appDataPath) + ? appDataPath + : Path.Combine(builder.Environment.ContentRootPath, appDataPath); + + // Override app data path per fixture via PostConfigure (no env var needed). + builder.Services.PostConfigure(options => + { + options.ShellsApplicationDataPath = resolvedAppDataPath; + }); + + // Override database config via IConfiguration (higher priority than env vars) + // so we never need to mutate global environment variables. + if (!string.IsNullOrEmpty(_originalConnectionString) && !string.IsNullOrEmpty(_originalDatabaseProvider)) + { + var connectionString = _originalConnectionString; + + if (!string.IsNullOrEmpty(instanceId)) + { + var dbName = ExtractDatabaseName(_originalConnectionString); + if (dbName is not null) + { + connectionString = ReplaceDatabaseName(_originalConnectionString, $"{dbName}_{instanceId}"); + EnsureCleanDatabase(connectionString, _originalDatabaseProvider); + } + } + + // Store for test helpers that need the fixture-specific connection string. + _currentConnectionString = connectionString; + + // Write tenants.json so OrchardCore picks up the per-fixture database. + Directory.CreateDirectory(resolvedAppDataPath); + File.WriteAllText( + Path.Combine(resolvedAppDataPath, "tenants.json"), + JsonSerializer.Serialize(new Dictionary + { + ["Default"] = new Dictionary + { + ["DatabaseProvider"] = _originalDatabaseProvider, + ["ConnectionString"] = connectionString, + }, + })); + + // Override the env-var-sourced configuration keys so ShellSettingsManager + // doesn't re-apply the original values with highest priority. + builder.Configuration["OrchardCore:ConnectionString"] = connectionString; + builder.Configuration["OrchardCore:DatabaseProvider"] = _originalDatabaseProvider; + } + + // Disable YesSql concurrency checks during setup. Each recipe step runs in a new + // scope with a new session, but the document cache can serve stale versions, causing + // ConcurrencyException on SiteSettings with external databases. + builder.Configuration["OrchardCore:OrchardCore_Documents:CheckConcurrency"] = "false"; + + builder.Logging.AddFilter(level => level >= LogLevel.Warning); + builder.Logging.AddProvider(loggerProvider); + } + + /// + /// Drops and recreates the fixture-specific database to ensure a clean state. + /// Each test fixture uses its own database (e.g., "app_SaasFixture") to avoid + /// cross-fixture interference. Dropping ensures no leftover tables from previous runs. + /// + private static void EnsureCleanDatabase(string connectionString, string databaseProvider) + { + var dbName = ExtractDatabaseName(connectionString); + if (dbName is null) + { + return; + } + + ValidateDatabaseName(dbName); + + var adminDb = databaseProvider switch + { + "Postgres" => "postgres", + "MySql" => "mysql", + "SqlConnection" => "master", + _ => null, + }; + + var serverConnectionString = ReplaceDatabaseName(connectionString, adminDb); + if (serverConnectionString is null) + { + return; + } + + using var connection = CreateConnection(serverConnectionString, databaseProvider); + if (connection is null) + { + return; + } + + connection.Open(); + + // Check if the database exists. + using var checkCommand = connection.CreateCommand(); + var param = checkCommand.CreateParameter(); + param.ParameterName = "@dbName"; + param.Value = dbName; + checkCommand.Parameters.Add(param); + + checkCommand.CommandText = databaseProvider switch + { + "Postgres" => "SELECT 1 FROM pg_database WHERE datname = @dbName", + "MySql" => "SELECT 1 FROM information_schema.schemata WHERE schema_name = @dbName", + "SqlConnection" => "SELECT 1 FROM sys.databases WHERE name = @dbName", + _ => null, + }; + + if (checkCommand.CommandText is null) + { + return; + } + + // Drop if it already exists so we start clean (no leftover tables from previous runs). + if (checkCommand.ExecuteScalar() is not null) + { + // Terminate active connections before dropping (required by Postgres < 13 which lacks DROP ... WITH (FORCE)). + if (databaseProvider == "Postgres") + { + using var terminateCommand = connection.CreateCommand(); + var terminateParam = terminateCommand.CreateParameter(); + terminateParam.ParameterName = "@dbName"; + terminateParam.Value = dbName; + terminateCommand.Parameters.Add(terminateParam); + terminateCommand.CommandText = "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = @dbName AND pid <> pg_backend_pid()"; + terminateCommand.ExecuteNonQuery(); + } + + using var dropCommand = connection.CreateCommand(); + dropCommand.CommandText = databaseProvider switch + { + "Postgres" => $"DROP DATABASE \"{dbName.Replace("\"", "\"\"")}\"", + "MySql" => $"DROP DATABASE `{dbName.Replace("`", "``")}`", + "SqlConnection" => $"ALTER DATABASE [{dbName.Replace("]", "]]")}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{dbName.Replace("]", "]]")}]", + _ => null, + }; + + dropCommand.ExecuteNonQuery(); + } + + // CREATE DATABASE is DDL and cannot be parameterized; quote per provider. + using var createCommand = connection.CreateCommand(); + createCommand.CommandText = databaseProvider switch + { + "Postgres" => $"CREATE DATABASE \"{dbName.Replace("\"", "\"\"")}\"", + "MySql" => $"CREATE DATABASE `{dbName.Replace("`", "``")}`", + "SqlConnection" => $"CREATE DATABASE [{dbName.Replace("]", "]]")}]", + _ => null, + }; + + createCommand.ExecuteNonQuery(); + } + + private static void ValidateDatabaseName(string dbName) + { + if (!System.Text.RegularExpressions.Regex.IsMatch(dbName, @"^[a-zA-Z0-9_\-]+$")) + { + throw new ArgumentException( + $"Database name '{dbName}' contains invalid characters. Only alphanumeric, underscore, and hyphen are allowed."); + } + } + + private static System.Data.Common.DbConnection CreateConnection(string connectionString, string databaseProvider) + { + return databaseProvider switch + { + "Postgres" => new Npgsql.NpgsqlConnection(connectionString), + "MySql" => new MySqlConnector.MySqlConnection(connectionString), + "SqlConnection" => new global::Microsoft.Data.SqlClient.SqlConnection(connectionString), + _ => null, + }; + } + + private static string ExtractDatabaseName(string connectionString) + { + var match = System.Text.RegularExpressions.Regex.Match( + connectionString, @"(?:Database|database)\s*=\s*([^;]+)", + System.Text.RegularExpressions.RegexOptions.IgnoreCase); + return match.Success ? match.Groups[1].Value.Trim() : null; + } + + private static string ReplaceDatabaseName(string connectionString, string newDbName) + { + if (newDbName is null) + { + return null; + } + + return System.Text.RegularExpressions.Regex.Replace( + connectionString, @"((?:Database|database)\s*=\s*)[^;]+", $"${{1}}{newDbName}", + System.Text.RegularExpressions.RegexOptions.IgnoreCase); + } + + private static string GetListeningAddress(WebApplication app) + { + var server = app.Services.GetRequiredService(); + var addresses = server.Features.Get(); + return addresses!.Addresses.First(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/SelectorHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/SelectorHelper.cs new file mode 100644 index 00000000000..875794ca534 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/SelectorHelper.cs @@ -0,0 +1,20 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class SelectorHelper +{ + public static ILocator GetByCy(this IPage page, string selector, bool exact = false) + { + return exact + ? page.Locator($"[data-cy=\"{selector}\"]") + : page.Locator($"[data-cy^=\"{selector}\"]"); + } + + public static ILocator FindByCy(this ILocator locator, string selector, bool exact = false) + { + return exact + ? locator.Locator($"[data-cy=\"{selector}\"]") + : locator.Locator($"[data-cy^=\"{selector}\"]"); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/TenantHelper.cs b/test/OrchardCore.Tests.Functional/Helpers/TenantHelper.cs new file mode 100644 index 00000000000..585dad59629 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/TenantHelper.cs @@ -0,0 +1,103 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Helpers; + +public static class TenantHelper +{ + public static async Task VisitTenantSetupPageAsync(this IPage page, TenantInfo tenant) + { + await page.GotoAsync("/Admin/Tenants"); + await page.Locator($"#btn-setup-{tenant.Name}").ClickAsync(); + } + + public static async Task SiteSetupAsync(this IPage page, TenantInfo tenant) + { + var config = TestUtils.DefaultConfig; + await page.Locator("#SiteName").FillAsync(tenant.Name); + + // Set recipe value directly. + var recipeName = page.Locator("#RecipeName"); + if (await recipeName.CountAsync() > 0) + { + await recipeName.EvaluateAsync( + "(el, val) => { el.value = val; el.dispatchEvent(new Event('change', { bubbles: true })); }", + tenant.SetupRecipe); + } + + // Set database provider to Sqlite if not already set. + var dbProvider = page.Locator("#DatabaseProvider"); + if (await dbProvider.CountAsync() > 0) + { + var currentValue = await dbProvider.InputValueAsync(); + if (string.IsNullOrEmpty(currentValue)) + { + await dbProvider.SelectOptionAsync("Sqlite"); + } + else if (!string.IsNullOrEmpty(tenant.TablePrefix)) + { + // When using a shared database (non-SQLite), set the table prefix to isolate data. + var tablePrefix = page.Locator("#TablePrefix"); + if (await tablePrefix.CountAsync() > 0 && await tablePrefix.IsVisibleAsync()) + { + await tablePrefix.FillAsync(tenant.TablePrefix); + } + } + } + + await page.Locator("#UserName").FillAsync(config.Username); + await page.Locator("#Email").FillAsync(config.Email); + await page.Locator("#Password").FillAsync(config.Password); + await page.Locator("#PasswordConfirmation").FillAsync(config.Password); + await page.Locator("#SubmitButton").ClickAsync(); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + } + + public static async Task CreateTenantAsync(this IPage page, TenantInfo tenant) + { + await page.GotoAsync("/Admin/Tenants"); + await page.Locator(".btn.create").First.ClickAsync(); + await page.Locator("#Name").FillAsync(tenant.Name); + await page.Locator("#Description").FillAsync($"Recipe: {tenant.SetupRecipe}. {tenant.Description}"); + await page.Locator("#RequestUrlPrefix").FillAsync(tenant.Prefix); + + // Select recipe if available in the dropdown, otherwise skip. + var recipeSelect = page.Locator("#RecipeName"); + var hasOption = await recipeSelect.Locator($"option[value=\"{tenant.SetupRecipe}\"]").CountAsync(); + if (hasOption > 0) + { + await recipeSelect.SelectOptionAsync(tenant.SetupRecipe); + } + + // Set database provider to Sqlite if not already set. + // When DatabaseConfigurationPreset is true (external DB configured on the parent), + // the #DatabaseProvider dropdown is not rendered — only the table prefix is shown. + var dbProvider = page.Locator("#DatabaseProvider"); + if (await dbProvider.CountAsync() > 0) + { + var currentValue = await dbProvider.InputValueAsync(); + if (string.IsNullOrEmpty(currentValue)) + { + await dbProvider.SelectOptionAsync("Sqlite"); + } + } + + // Always set the table prefix when available, regardless of whether the provider dropdown is visible. + var tablePrefix = page.Locator("#TablePrefix"); + if (await tablePrefix.CountAsync() > 0 && await tablePrefix.IsVisibleAsync()) + { + var tablePrefixValue = string.IsNullOrEmpty(tenant.TablePrefix) ? tenant.Name : tenant.TablePrefix; + await tablePrefix.FillAsync(tablePrefixValue); + } + + await page.Locator("button.create[type=\"submit\"]").ClickAsync(); + await page.WaitForLoadStateAsync(LoadState.NetworkIdle); + } + + public static async Task NewTenantAsync(this IPage page, TenantInfo tenant) + { + await page.LoginAsync(); + await page.CreateTenantAsync(tenant); + await page.VisitTenantSetupPageAsync(tenant); + await page.SiteSetupAsync(tenant); + } +} diff --git a/test/OrchardCore.Tests.Functional/Helpers/TestUtils.cs b/test/OrchardCore.Tests.Functional/Helpers/TestUtils.cs new file mode 100644 index 00000000000..a6445b8528f --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Helpers/TestUtils.cs @@ -0,0 +1,58 @@ +namespace OrchardCore.Tests.Functional.Helpers; + +public sealed class OrchardConfig +{ + public string Username { get; set; } = "admin"; + public string Email { get; set; } = "admin@orchard.com"; + public string Password { get; set; } = "Orchard1!"; +} + +public sealed class TenantInfo +{ + public string Name { get; set; } = string.Empty; + public string Prefix { get; set; } = string.Empty; + public string SetupRecipe { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public string TablePrefix { get; set; } = string.Empty; +} + +public static class TestUtils +{ + public static readonly OrchardConfig DefaultConfig = new(); + + public static TenantInfo GenerateTenantInfo(string setupRecipeName, string description = "") + { + var now = DateTime.UtcNow; + var today = now.Date; + var ms = (long)(now - today).TotalMilliseconds; + var uniqueName = "t" + ToBase32(ms); + + return new TenantInfo + { + Name = uniqueName, + Prefix = uniqueName, + SetupRecipe = setupRecipeName, + Description = description, + TablePrefix = uniqueName, + }; + } + + private static string ToBase32(long value) + { + const string digits = "0123456789abcdefghijklmnopqrstuv"; + if (value == 0) + { + return "0"; + } + + var result = new char[13]; + var index = result.Length; + while (value > 0) + { + result[--index] = digits[(int)(value % 32)]; + value /= 32; + } + + return new string(result, index, result.Length - index); + } +} diff --git a/test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj b/test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj index 8a1ac342122..299291bc808 100644 --- a/test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj +++ b/test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj @@ -2,7 +2,31 @@ $(CommonTargetFrameworks) + Exe false + $(NoWarn);CA1707 + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/OrchardCore.Tests.Functional/README.md b/test/OrchardCore.Tests.Functional/README.md new file mode 100644 index 00000000000..e095be5bcf7 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/README.md @@ -0,0 +1,161 @@ +# Functional Tests (`OrchardCore.Tests.Functional`) + +End-to-end browser tests for OrchardCore using [Playwright](https://playwright.dev/dotnet/) and xUnit. The tests launch OrchardCore in-process on a dynamic port, then drive a headless Chromium browser to verify setup, theming, login, and multi-tenancy. + +## Prerequisites + +- .NET SDK (current version) +- Playwright Chromium browser (installed automatically on first build, or manually via the command below) + +## Running the tests + +Build the project and install the Playwright browser: + +```bash +dotnet build -c Release test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj +dotnet exec test/OrchardCore.Tests.Functional/bin/Release/net10.0/Microsoft.Playwright.dll install chromium +``` + +Run all tests: + +```bash +dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build +``` + +Run only CMS or MVC tests: + +```bash +dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Cms*" +dotnet test --project test/OrchardCore.Tests.Functional/OrchardCore.Tests.Functional.csproj -c Release --no-build --filter-class "*Mvc*" +``` + +## Architecture + +### In-process hosting + +Tests use `OrchardTestServer`, which builds and starts OrchardCore in-process using `WebApplication.CreateBuilder` with the same configuration as the actual `Program.cs` entry points. Each test class fixture gets its own server instance on a dynamic port, with an isolated `App_Data_Tests_{FixtureName}` directory and (when using shared databases) a fixture-specific database. + +### Parallel execution + +Test fixtures run in parallel. Each fixture is fully isolated: + +- **App data**: Each fixture gets its own `App_Data_Tests_{FixtureName}` directory. +- **Database**: When using shared database servers (MySQL, PostgreSQL, SQL Server), each fixture drops and recreates its own database (e.g., `app_AgencyFixture`) to ensure a clean state. +- **Configuration**: Database env vars (`OrchardCore__ConnectionString`, `OrchardCore__DatabaseProvider`) are captured once at process start and immediately cleared. Each host receives its per-fixture connection string via `tenants.json` and `builder.Configuration`. +- **Recipes**: Test-only recipes are served from embedded assembly resources via `EmbeddedRecipeHarvester`, eliminating shared filesystem state. + +Parallelism is controlled by `maxParallelThreads` in `xunit.runner.json` (defaults to CPU core count when omitted). + +### Test structure + +``` +test/OrchardCore.Tests.Functional/ + Helpers/ + OrchardTestServer.cs # Builds and runs OrchardCore in-process + OrchardTestFixture.cs # Manages Playwright browser + server lifecycle + EmbeddedRecipeHarvester.cs # Serves test recipes from embedded resources + AuthHelper.cs # IPage.LoginAsync() extension + TenantHelper.cs # IPage.SiteSetupAsync(), CreateTenantAsync() extensions + ButtonHelper.cs # IPage.ClickSaveAsync() etc. extensions + ConfigurationHelper.cs # IPage.SetPageSizeAsync() extension + FeatureHelper.cs # IPage.EnableFeatureAsync() / DisableFeatureAsync() + SelectorHelper.cs # IPage.GetByCy() / FindByCy() for data-cy attributes + TestUtils.cs # OrchardConfig, TenantInfo, GenerateTenantInfo() + Tests/ + Cms/ + CmsRecipeFixture.cs # Base fixture: starts app, runs setup with a recipe + CmsTestBase.cs # Base test class with log assertion in teardown + AgencyTests.cs # Tests for the Agency recipe + BlogTests.cs # Tests for the Blog recipe + ComingSoonTests.cs # Tests for the ComingSoon recipe + HeadlessTests.cs # Tests for the Headless recipe + MigrationsTests.cs # Tests for database migrations via custom recipe + SaasFixture.cs # Fixture for SaaS multi-tenancy tests + SaasTests.cs # Tests tenant creation and isolation + Mvc/ + MvcSetupFixture.cs # Fixture for the MVC HelloWorld app + MvcTests.cs # Smoke test for MVC module + Fixtures/ + migrations.recipe.json # Embedded recipe for testing database migrations +``` + +### Adding test recipes + +Place any `.recipe.json` file in the `Fixtures/` folder. The csproj embeds `Fixtures/**/*.json` as assembly resources, and `EmbeddedRecipeHarvester` automatically discovers and serves them — no manual registration needed. + +### Fixture hierarchy + +Tests follow a layered fixture pattern: + +1. **`OrchardTestServer`** - Builds and starts the host, manages database isolation, captures logs via `FakeLoggerProvider`. +2. **`OrchardTestFixture`** - Wraps `OrchardTestServer` with Playwright browser/context lifecycle, tracing, and app data cleanup. +3. **`CmsRecipeFixture`** - Abstract base that runs site setup with a specific recipe during initialization. Concrete fixtures: `AgencyFixture`, `BlogFixture`, `ComingSoonFixture`, `HeadlessFixture`, `MigrationsFixture`. +4. **`CmsTestBase`** - Generic base test class that calls `AssertNoLoggedIssues()` in teardown. + +### Helper extensions + +All helpers are extension methods on Playwright's `IPage`, enabling fluent test code: + +```csharp +var page = await Fixture.CreatePageAsync(); +await page.LoginAsync(); +await page.GotoAsync("/Admin"); +await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); +await page.CloseAsync(); +``` + +### Log assertions + +A `FakeLoggerProvider` (from `Microsoft.Extensions.Diagnostics.Testing`) captures all Warning+ log entries during the test. After each test, `AssertNoLoggedIssues()` fails if any Warning or higher message was logged, catching server-side issues that may be invisible in the browser. A specific known benign DataProtection warning is filtered out. + +## Environment variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `PLAYWRIGHT_TRACING` | Enable Playwright tracing (set to any value) | Disabled | +| `ORCHARD_EXTERNAL` | Skip in-process hosting, use an externally running app | Not set | +| `ORCHARD_URL` | Base URL when using `ORCHARD_EXTERNAL` | `http://localhost:5000` | +| `OrchardCore__DatabaseProvider` | Database provider (`Postgres`, `MySql`, `SqlConnection`) | SQLite | +| `OrchardCore__ConnectionString` | Connection string for the database provider | Not set | + +## Testing with external databases + +Helper scripts spin up a Docker container and run the CMS tests with the same configuration as CI. + +**Linux / macOS:** + +```bash +cd test/OrchardCore.Tests.Functional + +./run-db-tests.sh postgres # PostgreSQL +./run-db-tests.sh mysql # MySQL +./run-db-tests.sh mssql # SQL Server +./run-db-tests.sh sqlite # SQLite (no container) +./run-db-tests.sh all # All databases sequentially +./run-db-tests.sh cleanup # Remove test containers +``` + +**Windows (PowerShell):** + +```powershell +cd test/OrchardCore.Tests.Functional + +.\run-db-tests.ps1 postgres # PostgreSQL +.\run-db-tests.ps1 mysql # MySQL +.\run-db-tests.ps1 mssql # SQL Server +.\run-db-tests.ps1 sqlite # SQLite (no container) +.\run-db-tests.ps1 all # All databases sequentially +.\run-db-tests.ps1 cleanup # Remove test containers +``` + +`run-db-tests.ps1` can also be used on Linux/macOS via [PowerShell](https://github.com/PowerShell/PowerShell). If `pwsh` is not available, install it from the [PowerShell GitHub releases page](https://github.com/PowerShell/PowerShell/releases/latest). + +Requires Docker. + +## Playwright tracing + +When `PLAYWRIGHT_TRACING` is set, traces are saved to `test/OrchardCore.Tests.Functional/traces/`. View them at . + +## CI + +The `functional_all_db.yml` workflow runs these tests against SQLite, PostgreSQL, MySQL, and SQL Server. Tracing is enabled by default in CI, and trace files are uploaded as artifacts on failure. diff --git a/test/OrchardCore.Tests.Functional/Readme.md b/test/OrchardCore.Tests.Functional/Readme.md deleted file mode 100644 index 178fa0536e1..00000000000 --- a/test/OrchardCore.Tests.Functional/Readme.md +++ /dev/null @@ -1,48 +0,0 @@ -# Cypress E2E Testing Suite - -## Prerequisites - -To get started, install the required packages by running: - -```bash -npm install -``` - -## Available Commands - -The following commands are defined in `package.json`: - -- **Run CMS Tests**: `npm run cms:test` - Executes CMS-specific tests. *(This is usually the primary command to use)* -- **Run MVC Tests**: `npm run mvc:test` - Runs tests for MVC. -- **Run CMS Tests in UI**: `npm run cms:cypress` - Launches CMS tests in the Cypress interactive UI. -- **Run MVC Tests in UI**: `npm run mvc:cypress` - Launches MVC tests in the Cypress UI. -- **Build Orchard Core**: `npm run cms:build` - Builds or rebuilds the Orchard Core environment. -- **Host Orchard Core**: `npm run cms:host` - Starts the Orchard Core server. -- **Generate Blog Data**: `npm run gen:blog` - Generates sample data for the blog recipe. - -## Creating a New CMS Test - -### Adding a New Test Suite - -For tests requiring a fresh tenant, create a new file in `./cms-tests/cypress/integration`. Tests in this folder execute in alphabetical order. - -### Adding a Test to an Existing Suite - -To add tests to an existing scenario, open any file in `./cms-tests/cypress/integration` and include the necessary assertions. - -## Cypress Commands for Orchard Core - -Each test scenario uses custom commands tailored for Orchard Core, such as `login` and `createTenant`. These commands are located in `./cypress-commands/src`. - -To update these commands, use the `rollup` script to bundle them into the `./cypress-commands/dist` folder: - -```bash -cd ./cypress-commands -npm run build -``` - -Both the `src` and `dist` folders should be included in source control. - -## NPM Package - -The `./cypress-commands` folder contains an npm package, [cypress-orchardcore](https://www.npmjs.com/package/cypress-orchardcore), published by [@jptissot](https://github.com/jptissot). This package allows other Orchard Core applications to leverage the testing framework. diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/AgencyTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/AgencyTests.cs new file mode 100644 index 00000000000..08f44186eae --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/AgencyTests.cs @@ -0,0 +1,28 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class AgencyTests : CmsTestBase, IClassFixture +{ + public AgencyTests(AgencyFixture fixture) : base(fixture) { } + + [Fact] + public async Task DisplaysTheHomePageOfTheAgencyTheme() + { + var page = await Fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.Locator("#services")).ToContainTextAsync("Lorem ipsum dolor sit amet consectetur"); + await page.CloseAsync(); + } + + [Fact] + public async Task AgencyAdminLoginShouldWork() + { + var page = await Fixture.CreatePageAsync(); + await page.LoginAsync(); + await page.GotoAsync("/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/BlogTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/BlogTests.cs new file mode 100644 index 00000000000..93782254b8b --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/BlogTests.cs @@ -0,0 +1,28 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class BlogTests : CmsTestBase, IClassFixture +{ + public BlogTests(BlogFixture fixture) : base(fixture) { } + + [Fact] + public async Task DisplaysTheHomePageOfTheBlogRecipe() + { + var page = await Fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.Locator(".subheading")).ToContainTextAsync("This is the description of your blog"); + await page.CloseAsync(); + } + + [Fact] + public async Task BlogAdminLoginShouldWork() + { + var page = await Fixture.CreatePageAsync(); + await page.LoginAsync(); + await page.GotoAsync("/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/CmsRecipeFixture.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/CmsRecipeFixture.cs new file mode 100644 index 00000000000..ffdb15337de --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/CmsRecipeFixture.cs @@ -0,0 +1,81 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public abstract class CmsRecipeFixture : IAsyncLifetime +{ + private readonly OrchardTestFixture _testFixture; + + protected abstract string RecipeName { get; } + + public IBrowser Browser => _testFixture.Browser; + public string BaseUrl => _testFixture.BaseUrl; + + protected CmsRecipeFixture() + { + _testFixture = new OrchardTestFixture(instanceId: GetType().Name); + } + + public async ValueTask InitializeAsync() + { + await _testFixture.InitializeAsync(); + + var page = await CreatePageAsync(); + try + { + await page.GotoAsync("/"); + + if (await page.Locator("#SiteName").CountAsync() > 0) + { + await page.SiteSetupAsync(new TenantInfo + { + Name = $"Testing {RecipeName}", + Prefix = string.Empty, + SetupRecipe = RecipeName, + }); + } + } + finally + { + await page.CloseAsync(); + } + } + + public void AssertNoLoggedIssues() => _testFixture.AssertNoLoggedIssues(); + + public async Task CreatePageAsync() + { + return await _testFixture.CreatePageAsync(); + } + + public async ValueTask DisposeAsync() + { + await _testFixture.DisposeAsync(); + } +} + +public sealed class AgencyFixture : CmsRecipeFixture +{ + protected override string RecipeName => "Agency"; +} + +public sealed class BlogFixture : CmsRecipeFixture +{ + protected override string RecipeName => "Blog"; +} + +public sealed class ComingSoonFixture : CmsRecipeFixture +{ + protected override string RecipeName => "ComingSoon"; +} + +public sealed class HeadlessFixture : CmsRecipeFixture +{ + protected override string RecipeName => "Headless"; +} + +public sealed class MigrationsFixture : CmsRecipeFixture +{ + protected override string RecipeName => "Migrations"; +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/CmsTestBase.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/CmsTestBase.cs new file mode 100644 index 00000000000..0e18e8cc3d0 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/CmsTestBase.cs @@ -0,0 +1,20 @@ +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public abstract class CmsTestBase : IAsyncLifetime + where TFixture : CmsRecipeFixture +{ + protected TFixture Fixture { get; } + + protected CmsTestBase(TFixture fixture) + { + Fixture = fixture; + } + + public ValueTask InitializeAsync() => ValueTask.CompletedTask; + + public virtual ValueTask DisposeAsync() + { + Fixture.AssertNoLoggedIssues(); + return ValueTask.CompletedTask; + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/ComingSoonTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/ComingSoonTests.cs new file mode 100644 index 00000000000..0b8aa094784 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/ComingSoonTests.cs @@ -0,0 +1,29 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class ComingSoonTests : CmsTestBase, IClassFixture +{ + public ComingSoonTests(ComingSoonFixture fixture) : base(fixture) { } + + [Fact] + public async Task DisplaysTheHomePageOfTheComingSoonTheme() + { + var page = await Fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.Locator("h1")).ToContainTextAsync("Coming Soon"); + await Assertions.Expect(page.Locator("p")).ToContainTextAsync("We're working hard to finish the development of this site."); + await page.CloseAsync(); + } + + [Fact] + public async Task ComingSoonAdminLoginShouldWork() + { + var page = await Fixture.CreatePageAsync(); + await page.LoginAsync(); + await page.GotoAsync("/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/HeadlessTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/HeadlessTests.cs new file mode 100644 index 00000000000..d826183d33b --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/HeadlessTests.cs @@ -0,0 +1,28 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class HeadlessTests : CmsTestBase, IClassFixture +{ + public HeadlessTests(HeadlessFixture fixture) : base(fixture) { } + + [Fact] + public async Task DisplaysTheLoginScreenForTheHeadlessTheme() + { + var page = await Fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.Locator("h1")).ToContainTextAsync("Log in"); + await page.CloseAsync(); + } + + [Fact] + public async Task HeadlessAdminLoginShouldWork() + { + var page = await Fixture.CreatePageAsync(); + await page.LoginAsync(); + await page.GotoAsync("/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/MigrationsTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/MigrationsTests.cs new file mode 100644 index 00000000000..4913b4e7717 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/MigrationsTests.cs @@ -0,0 +1,28 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class MigrationsTests : CmsTestBase, IClassFixture +{ + public MigrationsTests(MigrationsFixture fixture) : base(fixture) { } + + [Fact] + public async Task DisplaysTheHomePageOfTheMigrationsRecipe() + { + var page = await Fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.GetByText("Testing features having database migrations")).ToBeVisibleAsync(); + await page.CloseAsync(); + } + + [Fact] + public async Task MigrationsAdminLoginShouldWork() + { + var page = await Fixture.CreatePageAsync(); + await page.LoginAsync(); + await page.GotoAsync("/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/SaasFixture.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/SaasFixture.cs new file mode 100644 index 00000000000..9f3c4fdeef3 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/SaasFixture.cs @@ -0,0 +1,58 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class SaasFixture : IAsyncLifetime +{ + private readonly OrchardTestFixture _testFixture = new(instanceId: nameof(SaasFixture)); + + public IBrowser Browser => _testFixture.Browser; + public string BaseUrl => _testFixture.BaseUrl; + public TenantInfo Tenant { get; private set; } + + public async ValueTask InitializeAsync() + { + await _testFixture.InitializeAsync(); + + var page = await CreatePageAsync(); + try + { + await page.GotoAsync("/"); + + if (await page.Locator("#SiteName").CountAsync() > 0) + { + await page.SiteSetupAsync(new TenantInfo + { + Name = "Testing SaaS", + Prefix = string.Empty, + SetupRecipe = "SaaS", + }); + } + + // Create a test tenant to verify multi-tenancy. + Tenant = TestUtils.GenerateTenantInfo("SaaS"); + await page.LoginAsync(); + await page.SetPageSizeAsync(string.Empty, "100"); + await page.CreateTenantAsync(Tenant); + await page.VisitTenantSetupPageAsync(Tenant); + await page.SiteSetupAsync(Tenant); + } + finally + { + await page.CloseAsync(); + } + } + + public void AssertNoLoggedIssues() => _testFixture.AssertNoLoggedIssues(); + + public async Task CreatePageAsync() + { + return await _testFixture.CreatePageAsync(); + } + + public async ValueTask DisposeAsync() + { + await _testFixture.DisposeAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Cms/SaasTests.cs b/test/OrchardCore.Tests.Functional/Tests/Cms/SaasTests.cs new file mode 100644 index 00000000000..9b0bed9cd4c --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Cms/SaasTests.cs @@ -0,0 +1,41 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Cms; + +public sealed class SaasTests : IClassFixture, IAsyncLifetime +{ + private readonly SaasFixture _fixture; + + public SaasTests(SaasFixture fixture) + { + _fixture = fixture; + } + + public ValueTask InitializeAsync() => ValueTask.CompletedTask; + + public ValueTask DisposeAsync() + { + _fixture.AssertNoLoggedIssues(); + return ValueTask.CompletedTask; + } + + [Fact] + public async Task DisplaysTheHomePageOfTheSaasTheme() + { + var page = await _fixture.CreatePageAsync(); + await page.GotoAsync($"/{_fixture.Tenant.Prefix}"); + await Assertions.Expect(page.Locator("h4")).ToContainTextAsync("Welcome to Orchard Core, your site has been successfully set up."); + await page.CloseAsync(); + } + + [Fact] + public async Task SaasAdminLoginShouldWork() + { + var page = await _fixture.CreatePageAsync(); + await page.LoginAsync($"/{_fixture.Tenant.Prefix}"); + await page.GotoAsync($"/{_fixture.Tenant.Prefix}/Admin"); + await Assertions.Expect(page.Locator(".menu-admin")).ToHaveAttributeAsync("id", "adminMenu"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcSetupFixture.cs b/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcSetupFixture.cs new file mode 100644 index 00000000000..28cc9341a36 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcSetupFixture.cs @@ -0,0 +1,29 @@ +using Microsoft.Playwright; +using OrchardCore.Tests.Functional.Helpers; + +namespace OrchardCore.Tests.Functional.Tests.Mvc; + +public sealed class MvcSetupFixture : IAsyncLifetime +{ + private readonly OrchardTestFixture _testFixture = new(isMvc: true); + + public IBrowser Browser => _testFixture.Browser; + public string BaseUrl => _testFixture.BaseUrl; + + public async ValueTask InitializeAsync() + { + await _testFixture.InitializeAsync(); + } + + public void AssertNoLoggedIssues() => _testFixture.AssertNoLoggedIssues(); + + public async Task CreatePageAsync() + { + return await _testFixture.CreatePageAsync(); + } + + public async ValueTask DisposeAsync() + { + await _testFixture.DisposeAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcTests.cs b/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcTests.cs new file mode 100644 index 00000000000..942683a539d --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Tests/Mvc/MvcTests.cs @@ -0,0 +1,30 @@ +using Microsoft.Playwright; + +namespace OrchardCore.Tests.Functional.Tests.Mvc; + +public sealed class MvcTests : IClassFixture, IAsyncLifetime +{ + private readonly MvcSetupFixture _fixture; + + public MvcTests(MvcSetupFixture fixture) + { + _fixture = fixture; + } + + public ValueTask InitializeAsync() => ValueTask.CompletedTask; + + public ValueTask DisposeAsync() + { + _fixture.AssertNoLoggedIssues(); + return ValueTask.CompletedTask; + } + + [Fact] + public async Task ShouldDisplayHelloWorld() + { + var page = await _fixture.CreatePageAsync(); + await page.GotoAsync("/"); + await Assertions.Expect(page.Locator("body")).ToContainTextAsync("Hello World"); + await page.CloseAsync(); + } +} diff --git a/test/OrchardCore.Tests.Functional/Usings.cs b/test/OrchardCore.Tests.Functional/Usings.cs new file mode 100644 index 00000000000..3b7dd23a514 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/Usings.cs @@ -0,0 +1,10 @@ +global using System; +global using System.Collections.Generic; +global using System.Diagnostics; +global using System.IO; +global using System.Linq; +global using System.Net.Http; +global using System.Reflection; +global using System.Threading; +global using System.Threading.Tasks; +global using Xunit; diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress.json b/test/OrchardCore.Tests.Functional/cms-tests/cypress.json deleted file mode 100644 index c2423a36901..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "baseUrl": "http://localhost:5000", - "video": false, - "orchard": { - "username":"admin", - "email": "admin@orchard.com", - "password": "Orchard1!" - } -} diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/000-saas-setup.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/000-saas-setup.js deleted file mode 100644 index 214c84e6ae4..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/000-saas-setup.js +++ /dev/null @@ -1,15 +0,0 @@ -/// - -const sassSite = { - name: "Testing SaaS", - setupRecipe: "SaaS", - } - -describe('Setup SaaS', function () { - it('Successfully setup the SaaS default tenant', function () { - cy.visit('/'); - cy.siteSetup(sassSite); - cy.login(sassSite); - cy.setPageSize(sassSite, "100"); - }); -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/agency-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/agency-test.js deleted file mode 100644 index 28cced3084c..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/agency-test.js +++ /dev/null @@ -1,23 +0,0 @@ -/// - -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('Agency Tests', function () { - let tenant; - - before(() => { - tenant = generateTenantInfo("Agency") - cy.newTenant(tenant); - }) - - it('Displays the home page of the Agency theme', function(){ - cy.visit(`${tenant.prefix}`); - cy.get('#services').should('contain.text', 'Lorem ipsum dolor sit amet consectetur'); - }) - - it('Agency admin login should work', function(){ - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/blog-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/blog-test.js deleted file mode 100644 index e8f1be29125..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/blog-test.js +++ /dev/null @@ -1,24 +0,0 @@ -/// - -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('Blog Tests', function () { - let tenant; - - before(() => { - // generate the blog tenant - tenant = generateTenantInfo("Blog") - cy.newTenant(tenant); - }) - - it('Displays the home page of the blog recipe', function(){ - cy.visit(`${tenant.prefix}`); - cy.get('.subheading').should('contain.text', 'This is the description of your blog'); - }) - - it('Blog admin login should work', function(){ - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/comingsoon-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/comingsoon-test.js deleted file mode 100644 index 405511b9586..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/comingsoon-test.js +++ /dev/null @@ -1,23 +0,0 @@ -/// -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('ComingSoon Recipe test', function () { - let tenant; - - before(() => { - tenant = generateTenantInfo("ComingSoon") - cy.newTenant(tenant); - }) - - it('Displays the home page of the ComingSoon theme', function () { - cy.visit(`${tenant.prefix}`); - cy.get('h1').should('contain.text', 'Coming Soon'); - cy.get('p').should('contain.text', "We're working hard to finish the development of this site."); - }) - - it('ComingSoon admin login should work', function () { - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/headless-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/headless-test.js deleted file mode 100644 index af86eada00d..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/headless-test.js +++ /dev/null @@ -1,22 +0,0 @@ -/// -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('Headless Recipe test', function () { - let tenant; - - before(() => { - tenant = generateTenantInfo("Headless") - cy.newTenant(tenant); - }) - - it('Displays the login screen when accessing the root of the Headless theme', function(){ - cy.visit(`${tenant.prefix}`); - cy.get('h1').should('contain.text', 'Log in'); - }) - - it('Headless admin login should work', function(){ - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/migrations-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/migrations-test.js deleted file mode 100644 index 863b42ccaee..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/migrations-test.js +++ /dev/null @@ -1,24 +0,0 @@ -/// - -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('Migrations Tests', function () { - let tenant; - - before(() => { - // generate the migrations tenant - tenant = generateTenantInfo("Migrations") - cy.newTenant(tenant); - }) - - it('Displays the home page of the migrations recipe', function () { - cy.visit(`${tenant.prefix}`); - cy.get('.container').should('contain.text', 'Testing features having database migrations'); - }) - - it('Migrations admin login should work', function () { - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/sass-test.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/sass-test.js deleted file mode 100644 index c5c32f5bea8..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/integration/sass-test.js +++ /dev/null @@ -1,22 +0,0 @@ -/// -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe('SaaS Recipe test', function () { - let tenant; - - before(() => { - tenant = generateTenantInfo("SaaS") - cy.newTenant(tenant); - }) - - it('Displays the home page of the SaaS theme', function(){ - cy.visit(`${tenant.prefix}`); - cy.get('h4').should('contain.text', 'Welcome to Orchard Core, your site has been successfully set up.'); - }) - - it('SaaS admin login should work', function(){ - cy.login(tenant); - cy.visit(`${tenant.prefix}/Admin`); - cy.get('.menu-admin').should('have.id', 'adminMenu') - }) -}); diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/plugins/index.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/plugins/index.js deleted file mode 100644 index fd170fba691..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/plugins/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/support/commands.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/support/commands.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/OrchardCore.Tests.Functional/cms-tests/cypress/support/index.js b/test/OrchardCore.Tests.Functional/cms-tests/cypress/support/index.js deleted file mode 100644 index 9c0d510c3cc..00000000000 --- a/test/OrchardCore.Tests.Functional/cms-tests/cypress/support/index.js +++ /dev/null @@ -1,21 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' -import 'cypress-orchardcore/dist' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/.npmignore b/test/OrchardCore.Tests.Functional/cypress-commands/.npmignore deleted file mode 100644 index 51dec43dc27..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -* -!README.md -!dist/* -!LICENSE diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/LICENSE b/test/OrchardCore.Tests.Functional/cypress-commands/LICENSE deleted file mode 100644 index 183936c000f..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/LICENSE +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License -https://opensource.org/licenses/BSD-3-Clause - -Copyright (c) .NET Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Orchard nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/README.md b/test/OrchardCore.Tests.Functional/cypress-commands/README.md deleted file mode 100644 index 79c89519867..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/README.md +++ /dev/null @@ -1,95 +0,0 @@ -# Cypress OrchardCore - -A collection of cypress commands for interacting with [OrchardCore CMS](https://github.com/OrchardCMS/OrchardCore). - -## Installation - -Install this package by running `npm install cypress-orchardcore` - -## Setup - -### Load the package in cypress support index file. - -```javascript -// cypress/support/index.js -import 'cypress-orchardcore' -``` - -### Orchard admin credentials - -First thing to do to use this package is to add the credentials to be used to interact with OrchardCore. These credentials must be added to the `cypress.json` config file under the `orchard` key. - -```json -{ - "baseUrl": "https://localhost:5001", - "orchard": { - "username":"admin", - "email": "admin@orchard.com", - "password": "Orchard1!" - } -} -``` - -### Orchard default tenant - -This library assumes that you will be testing OrchardCore by leveraging the [Tenants](https://docs.orchardcore.net/en/latest/reference/glossary/#tenant) feature. You **must** create a test that runs first and sets up the Default tenant using the [Software as a service](https://docs.orchardcore.net/en/latest/getting-started/starter-recipes/#saas-recipe-with-thetheme) setup recipe. - -To do so we suggest you create a test named `integration\000-setup-saas-site.js` with the following contents. - -```javascript -/// - -const sassTenant = { - name: "Testing SaaS", - setupRecipe: "SaaS", -} - -describe("Default tenant setup using SaaS recipe", function() { - it("Setup default tenant", function() { - cy.visit("/"); - cy.siteSetup(sassTenant); - cy.login() - // this is required to increase paging in the Tenants list page. Since we will be creating a lot of tenants during out testing. - cy.setPageSize(sassTenant, "100"); - }); -}); -``` - - -## Test Structure - -Since we need to create tenants to test OrchardCore, it is recommended to use cypress's before() hook to create a tenant to use in your suite of tests. -We recommend you use 1 tenant for each `describe()` - -```javascript -/// -import { generateTenantInfo } from 'cypress-orchardcore/dist/utils'; - -describe("VueForm Tests", function() { - let tenant; - - before(() => { - // generate a tenant for all tests below - tenant = generateTenantInfo("SetupRecipeName") - cy.newTenant(tenant); - cy.login(tenant); - cy.uploadRecipeJson(tenant, "fixturefile.json"); - }) - - it("DoesSomething", function() { - cy.visitContentPage(tenant, ""); - //... - }) - - it("DoesSomethingElse", function() { - - cy.visitContentPage(tenant, ""); - //... - - }) -}); -``` - -## Available Commands - -TODO diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.js b/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.js deleted file mode 100644 index de60819b6aa..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.js +++ /dev/null @@ -1,155 +0,0 @@ -'use strict'; - -Cypress.Commands.add("login", function({ prefix = ""}={}) { - const config = Cypress.config('orchard'); - cy.visit(`${prefix}/login`); - cy.get("#LoginForm_UserName").type(config.username); - cy.get("#LoginForm_Password").type(config.password); - cy.get("#LoginForm_UserName").closest('form').submit(); -}); - -Cypress.Commands.add("visitTenantSetupPage", ({ name }) => { - cy.visit("/Admin/Tenants"); - cy.get(`#btn-setup-${name}`).click(); -}); - -Cypress.Commands.add("siteSetup", ({ name, setupRecipe }) => { - const config = Cypress.config('orchard'); - cy.get("#SiteName").type(name); - cy.get("body").then($body => { - const elem = $body.find("#RecipeName"); - if (elem) { - elem.val(setupRecipe); - } - const db = $body.find("#DatabaseProvider"); - if(db.length > 0 && db.val() == "") { - db.val("Sqlite"); - } - }); - cy.get("#UserName").type(config.username); - cy.get("#Email").type(config.email); - cy.get("#Password").type(config.password); - cy.get("#PasswordConfirmation").type(config.password); - cy.get("#SubmitButton").click(); -}); -Cypress.Commands.add('newTenant', function(tenantInfo) { - cy.login(); - cy.createTenant(tenantInfo); - cy.visitTenantSetupPage(tenantInfo); - cy.siteSetup(tenantInfo); -}); - -Cypress.Commands.add("createTenant", ({ name, prefix, setupRecipe, description }) => { - // We create tenants on the SaaS tenant - cy.visit("/Admin/Tenants"); - cy.btnCreateClick(); - cy.get("#Name").type(name, {force:true}); - cy.get("#Description").type(`Recipe: ${setupRecipe}. ${description || ''}`, {force:true}); - cy.get("#RequestUrlPrefix").type(prefix, {force:true}); - cy.get("#RecipeName").select(setupRecipe); - cy.get("body").then($body => { - const db = $body.find("#DatabaseProvider"); - // if a database provider is already specified by an environment variable.. leave it as is - // this assumes that if you set the provider, you also set the connectionString - if (db.length > 0 && db.val() == "") { - db.val('Sqlite'); - } else { - //set the tablePrefix to the name. - const prefix = $body.find("#TablePrefix"); - if(prefix.length > 0){ - prefix.val(name); - } - } - }); - cy.btnCreateClick(); -}); - -Cypress.Commands.add("runRecipe", ({ prefix }, recipeName) => { - cy.visit(`${prefix}/Admin/Recipes`); - cy.get(`#btn-run-${recipeName}`).click(); - cy.btnModalOkClick(); -}); - -Cypress.Commands.add("uploadRecipeJson", ({ prefix }, fixturePath) => { - cy.fixture(fixturePath).then((data) => { - cy.visit(`${prefix}/Admin/DeploymentPlan/Import/Json`); - cy.get('.CodeMirror').should('be.visible'); - cy.get("body").then($body => { - $body.find(".CodeMirror")[0].CodeMirror.setValue(JSON.stringify(data)); - }); - cy.get('.ta-content > form').submit(); - // make sure the message-success alert is displayed - cy.get('.message-success').should('contain', "Recipe imported"); - }); - }); - -function byCy(id, exact) { - if (exact) { - return `[data-cy="${id}"]`; - } - return `[data-cy^="${id}"]`; -} - -Cypress.Commands.add('getByCy', (selector, exact = false) => { - return cy.get(byCy(selector, exact)); -}); - -Cypress.Commands.add( - 'findByCy', - {prevSubject: 'optional'}, - (subject, selector, exact = false) => { - return subject - ? cy.wrap(subject).find(byCy(selector, exact)) - : cy.find(byCy(selector, exact)); - }, -); - -Cypress.Commands.add("setPageSize", ({prefix = ""}, size) => { - cy.visit(`${prefix}/Admin/Settings/general`); - cy.get('#ISite_PageSize') - .clear() - .type(size); - cy.btnSaveClick(); - // wait until the success message is displayed - cy.get('.message-success'); -}); - -Cypress.Commands.add("enableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-enable-${featureName}`).click(); -}); - -Cypress.Commands.add("diableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-diable-${featureName}`).click(); -}); - -Cypress.Commands.add("visitContentPage", ({ prefix }, contentItemId) => { - cy.visit(`${prefix}/Contents/ContentItems/${contentItemId}`); -}); - -Cypress.Commands.add('btnCreateClick', function() { - cy.get('.btn.create').click(); -}); - -Cypress.Commands.add('btnSaveClick', function() { - cy.get('.btn.save').click(); -}); -Cypress.Commands.add('btnSaveContinueClick', function() { - cy.get('.dropdown-item.save-continue').click(); -}); - -Cypress.Commands.add('btnCancelClick', function() { - cy.get('.btn.cancel').click(); -}); - -Cypress.Commands.add('btnPublishClick', function() { - cy.get('.btn.public').click(); -}); -Cypress.Commands.add('btnPublishContinueClick', function() { - cy.get('.dropdown-item.publish-continue').click(); -}); - -Cypress.Commands.add('btnModalOkClick', function() { - cy.get("#modalOkButton").click(); -}); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.mjs b/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.mjs deleted file mode 100644 index 77e0ceb3cbf..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/index.mjs +++ /dev/null @@ -1,153 +0,0 @@ -Cypress.Commands.add("login", function({ prefix = ""}={}) { - const config = Cypress.config('orchard'); - cy.visit(`${prefix}/login`); - cy.get("#LoginForm_UserName").type(config.username); - cy.get("#LoginForm_Password").type(config.password); - cy.get("#LoginForm_UserName").closest('form').submit(); -}); - -Cypress.Commands.add("visitTenantSetupPage", ({ name }) => { - cy.visit("/Admin/Tenants"); - cy.get(`#btn-setup-${name}`).click(); -}); - -Cypress.Commands.add("siteSetup", ({ name, setupRecipe }) => { - const config = Cypress.config('orchard'); - cy.get("#SiteName").type(name); - cy.get("body").then($body => { - const elem = $body.find("#RecipeName"); - if (elem) { - elem.val(setupRecipe); - } - const db = $body.find("#DatabaseProvider"); - if(db.length > 0 && db.val() == "") { - db.val("Sqlite"); - } - }); - cy.get("#UserName").type(config.username); - cy.get("#Email").type(config.email); - cy.get("#Password").type(config.password); - cy.get("#PasswordConfirmation").type(config.password); - cy.get("#SubmitButton").click(); -}); -Cypress.Commands.add('newTenant', function(tenantInfo) { - cy.login(); - cy.createTenant(tenantInfo); - cy.visitTenantSetupPage(tenantInfo); - cy.siteSetup(tenantInfo); -}); - -Cypress.Commands.add("createTenant", ({ name, prefix, setupRecipe, description }) => { - // We create tenants on the SaaS tenant - cy.visit("/Admin/Tenants"); - cy.btnCreateClick(); - cy.get("#Name").type(name, {force:true}); - cy.get("#Description").type(`Recipe: ${setupRecipe}. ${description || ''}`, {force:true}); - cy.get("#RequestUrlPrefix").type(prefix, {force:true}); - cy.get("#RecipeName").select(setupRecipe); - cy.get("body").then($body => { - const db = $body.find("#DatabaseProvider"); - // if a database provider is already specified by an environment variable.. leave it as is - // this assumes that if you set the provider, you also set the connectionString - if (db.length > 0 && db.val() == "") { - db.val('Sqlite'); - } else { - //set the tablePrefix to the name. - const prefix = $body.find("#TablePrefix"); - if(prefix.length > 0){ - prefix.val(name); - } - } - }); - cy.btnCreateClick(); -}); - -Cypress.Commands.add("runRecipe", ({ prefix }, recipeName) => { - cy.visit(`${prefix}/Admin/Recipes`); - cy.get(`#btn-run-${recipeName}`).click(); - cy.btnModalOkClick(); -}); - -Cypress.Commands.add("uploadRecipeJson", ({ prefix }, fixturePath) => { - cy.fixture(fixturePath).then((data) => { - cy.visit(`${prefix}/Admin/DeploymentPlan/Import/Json`); - cy.get('.CodeMirror').should('be.visible'); - cy.get("body").then($body => { - $body.find(".CodeMirror")[0].CodeMirror.setValue(JSON.stringify(data)); - }); - cy.get('.ta-content > form').submit(); - // make sure the message-success alert is displayed - cy.get('.message-success').should('contain', "Recipe imported"); - }); - }); - -function byCy(id, exact) { - if (exact) { - return `[data-cy="${id}"]`; - } - return `[data-cy^="${id}"]`; -} - -Cypress.Commands.add('getByCy', (selector, exact = false) => { - return cy.get(byCy(selector, exact)); -}); - -Cypress.Commands.add( - 'findByCy', - {prevSubject: 'optional'}, - (subject, selector, exact = false) => { - return subject - ? cy.wrap(subject).find(byCy(selector, exact)) - : cy.find(byCy(selector, exact)); - }, -); - -Cypress.Commands.add("setPageSize", ({prefix = ""}, size) => { - cy.visit(`${prefix}/Admin/Settings/general`); - cy.get('#ISite_PageSize') - .clear() - .type(size); - cy.btnSaveClick(); - // wait until the success message is displayed - cy.get('.message-success'); -}); - -Cypress.Commands.add("enableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-enable-${featureName}`).click(); -}); - -Cypress.Commands.add("diableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-diable-${featureName}`).click(); -}); - -Cypress.Commands.add("visitContentPage", ({ prefix }, contentItemId) => { - cy.visit(`${prefix}/Contents/ContentItems/${contentItemId}`); -}); - -Cypress.Commands.add('btnCreateClick', function() { - cy.get('.btn.create').click(); -}); - -Cypress.Commands.add('btnSaveClick', function() { - cy.get('.btn.save').click(); -}); -Cypress.Commands.add('btnSaveContinueClick', function() { - cy.get('.dropdown-item.save-continue').click(); -}); - -Cypress.Commands.add('btnCancelClick', function() { - cy.get('.btn.cancel').click(); -}); - -Cypress.Commands.add('btnPublishClick', function() { - cy.get('.btn.public').click(); -}); -Cypress.Commands.add('btnPublishContinueClick', function() { - cy.get('.dropdown-item.publish-continue').click(); -}); - -Cypress.Commands.add('btnModalOkClick', function() { - cy.get("#modalOkButton").click(); -}); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.js b/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.js deleted file mode 100644 index 179dea874aa..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.js +++ /dev/null @@ -1,111 +0,0 @@ -'use strict'; - -// This module was originally build by the OrchardCore team -const child_process = require("child_process"); -const fs = require("fs-extra"); -const path = require("path"); - -global.log = function (msg) { - let now = new Date().toLocaleTimeString(); - console.log(`[${now}] ${msg}\n`); - - if (msg.indexOf("Exception") >= 0) { - throw new Error("An exception was detected"); - } - - if (msg.indexOf("fail:") == 0) { - throw new Error("An error was logged"); - } -}; - -// Build the dotnet application in release mode -function build(dir, dotnetVersion) { - global.log("Building ..."); - child_process.spawnSync("dotnet", ["build", "-c", "Release", "-f", dotnetVersion], { cwd: dir }); -} - -// destructive action that deletes the App_Data folder -function deleteDirectory(dir) { - fs.removeSync(dir); - global.log(`${dir} deleted`); -} - -// Copy the migrations recipe. -function copyMigrationsRecipeFile(dir) { - - const recipeFilePath = 'Recipes/migrations.recipe.json'; - - if (!fs.existsSync(`./${recipeFilePath}`) || fs.existsSync(`${dir}/${recipeFilePath}`)) { - return; - } - - if (!fs.existsSync(`${dir}/Recipes`)) { - fs.mkdirSync(`${dir}/Recipes`); - } - - fs.copyFile(`./${recipeFilePath}`, `${dir}/${recipeFilePath}`); - global.log(`migrations recipe copied to ${dir}/Recipes`); -} - -// Host the dotnet application, does not rebuild -function host(dir, assembly, { appDataLocation = './App_Data', dotnetVersion = 'net10.0' } = {}) { - if (fs.existsSync(path.join(dir, `bin/Release/${dotnetVersion}/`, assembly))) { - global.log("Application already built, skipping build"); - } else { - build(dir, dotnetVersion); - } - global.log("Starting application ..."); - - const ocEnv = {}; - ocEnv["ORCHARD_APP_DATA"] = appDataLocation; - - let server = child_process.spawn( - "dotnet", - [`bin/Release/${dotnetVersion}/` + assembly], - { cwd: dir, env: { ...process.env, ...ocEnv } } - ); - - server.stdout.on("data", data => { - global.log(data); - }); - - server.stderr.on("data", data => { - global.log(`stderr: ${data}`); - }); - - server.on("close", code => { - global.log(`Server process exited with code ${code}`); - }); - return server; -} - -// combines the functions above, useful when triggering tests from CI -function e2e(dir, assembly, { dotnetVersion = 'net10.0' } = {}) { - copyMigrationsRecipeFile(dir); - deleteDirectory(path.join(dir, "App_Data_Tests")); - var server = host(dir, assembly, { appDataLocation: "./App_Data_Tests", dotnetVersion }); - - // Wait for server to start up before launching Cypress - global.log("Waiting for server to start..."); - setTimeout(() => { - let test = child_process.exec("npx cypress run"); - test.stdout.on("data", data => { - console.log(data); - }); - - test.stderr.on("data", data => { - console.log(`stderr: ${data}`); - }); - - test.on("close", code => { - console.log(`Cypress process exited with code ${code}`); - server.kill("SIGINT"); - process.exit(code); - }); - }, 10000); // Wait 10 seconds for server to start -} - -exports.build = build; -exports.deleteDirectory = deleteDirectory; -exports.e2e = e2e; -exports.host = host; diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.mjs b/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.mjs deleted file mode 100644 index 563fc4f6f3f..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/test-runner.mjs +++ /dev/null @@ -1,106 +0,0 @@ -// This module was originally build by the OrchardCore team -const child_process = require("child_process"); -const fs = require("fs-extra"); -const path = require("path"); - -global.log = function (msg) { - let now = new Date().toLocaleTimeString(); - console.log(`[${now}] ${msg}\n`); - - if (msg.indexOf("Exception") >= 0) { - throw new Error("An exception was detected"); - } - - if (msg.indexOf("fail:") == 0) { - throw new Error("An error was logged"); - } -}; - -// Build the dotnet application in release mode -function build(dir, dotnetVersion) { - global.log("Building ..."); - child_process.spawnSync("dotnet", ["build", "-c", "Release", "-f", dotnetVersion], { cwd: dir }); -} - -// destructive action that deletes the App_Data folder -function deleteDirectory(dir) { - fs.removeSync(dir); - global.log(`${dir} deleted`); -} - -// Copy the migrations recipe. -function copyMigrationsRecipeFile(dir) { - - const recipeFilePath = 'Recipes/migrations.recipe.json'; - - if (!fs.existsSync(`./${recipeFilePath}`) || fs.existsSync(`${dir}/${recipeFilePath}`)) { - return; - } - - if (!fs.existsSync(`${dir}/Recipes`)) { - fs.mkdirSync(`${dir}/Recipes`); - } - - fs.copyFile(`./${recipeFilePath}`, `${dir}/${recipeFilePath}`); - global.log(`migrations recipe copied to ${dir}/Recipes`); -} - -// Host the dotnet application, does not rebuild -function host(dir, assembly, { appDataLocation = './App_Data', dotnetVersion = 'net10.0' } = {}) { - if (fs.existsSync(path.join(dir, `bin/Release/${dotnetVersion}/`, assembly))) { - global.log("Application already built, skipping build"); - } else { - build(dir, dotnetVersion); - } - global.log("Starting application ..."); - - const ocEnv = {}; - ocEnv["ORCHARD_APP_DATA"] = appDataLocation; - - let server = child_process.spawn( - "dotnet", - [`bin/Release/${dotnetVersion}/` + assembly], - { cwd: dir, env: { ...process.env, ...ocEnv } } - ); - - server.stdout.on("data", data => { - global.log(data); - }); - - server.stderr.on("data", data => { - global.log(`stderr: ${data}`); - }); - - server.on("close", code => { - global.log(`Server process exited with code ${code}`); - }); - return server; -} - -// combines the functions above, useful when triggering tests from CI -function e2e(dir, assembly, { dotnetVersion = 'net10.0' } = {}) { - copyMigrationsRecipeFile(dir); - deleteDirectory(path.join(dir, "App_Data_Tests")); - var server = host(dir, assembly, { appDataLocation: "./App_Data_Tests", dotnetVersion }); - - // Wait for server to start up before launching Cypress - global.log("Waiting for server to start..."); - setTimeout(() => { - let test = child_process.exec("npx cypress run"); - test.stdout.on("data", data => { - console.log(data); - }); - - test.stderr.on("data", data => { - console.log(`stderr: ${data}`); - }); - - test.on("close", code => { - console.log(`Cypress process exited with code ${code}`); - server.kill("SIGINT"); - process.exit(code); - }); - }, 10000); // Wait 10 seconds for server to start -} - -export { build, deleteDirectory, e2e, host }; diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.js b/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.js deleted file mode 100644 index 7be65a96bbb..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -// https://stackoverflow.com/questions/105034/how-to-create-guid-uuid - -function generateUniqueName() { - var date = new Date(); - var today = new Date(date.getFullYear(), date.getMonth(), date.getDate()); - return 't' + (date - today).toString(32); -} - -function generateTenantInfo(setupRecipeName, description) { - var uniqueName = generateUniqueName(); - return { - name: uniqueName, - prefix: uniqueName, - setupRecipe: setupRecipeName, - description - } -} - -exports.generateTenantInfo = generateTenantInfo; diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.mjs b/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.mjs deleted file mode 100644 index e9ade421fee..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/dist/utils.mjs +++ /dev/null @@ -1,19 +0,0 @@ -// https://stackoverflow.com/questions/105034/how-to-create-guid-uuid - -function generateUniqueName() { - var date = new Date(); - var today = new Date(date.getFullYear(), date.getMonth(), date.getDate()); - return 't' + (date - today).toString(32); -} - -function generateTenantInfo(setupRecipeName, description) { - var uniqueName = generateUniqueName(); - return { - name: uniqueName, - prefix: uniqueName, - setupRecipe: setupRecipeName, - description - } -} - -export { generateTenantInfo }; diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/package-lock.json b/test/OrchardCore.Tests.Functional/cypress-commands/package-lock.json deleted file mode 100644 index 6b0a31330b3..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/package-lock.json +++ /dev/null @@ -1,745 +0,0 @@ -{ - "name": "cypress-orchardcore", - "version": "0.4.7", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "cypress-orchardcore", - "version": "0.4.7", - "license": "MIT", - "dependencies": { - "fs-extra": "^10.0.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.0", - "rollup": "^4.22.4" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", - "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.1.1", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup/node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - } - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "@rollup/plugin-commonjs": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", - "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.1.1", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^2.3.1" - }, - "dependencies": { - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - } - } - }, - "@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "dependencies": { - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - } - } - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "dev": true, - "optional": true - }, - "@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", - "dev": true, - "requires": {} - }, - "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "optional": true, - "peer": true - }, - "rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", - "@types/estree": "1.0.5", - "fsevents": "~2.3.2" - }, - "dependencies": { - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - } - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - } - } -} diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/package.json b/test/OrchardCore.Tests.Functional/cypress-commands/package.json deleted file mode 100644 index d0c0a9144f4..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "cypress-orchardcore", - "version": "0.4.7", - "author": "The Orchard Team", - "description": "Cypress commands for Orchard Core", - "license": "MIT", - "main": "dist/index.js", - "module": "dist/index.mjs", - "homepage": "https://github.com/OrchardCms/OrchardCore#readme", - "repository": { - "type": "git", - "url": "git+https://github.com/OrchardCMS/OrchardCore.git" - }, - "bugs": { - "url": "https://github.com/OrchardCMS/OrchardCore/issues" - }, - "keywords": [ - "cypress", - "orchard-core", - "cms", - "dotnet-core", - "testing" - ], - "scripts": { - "build": "rollup -c --bundleConfigAsCjs", - "watch": "rollup -c -w" - }, - "dependencies": { - "fs-extra": "^10.0.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.0", - "rollup": "^4.22.4" - } -} diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/rollup.config.js b/test/OrchardCore.Tests.Functional/cypress-commands/rollup.config.js deleted file mode 100644 index 81c8477ceeb..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/rollup.config.js +++ /dev/null @@ -1,58 +0,0 @@ -import pkg from './package.json'; -import commonjs from '@rollup/plugin-commonjs'; - -const config = [ - { - input: './src/index.js', - output: [ - { - file: pkg.main, - format: 'cjs', - globals: { - Cypress: 'cypress', - }, - }, - { file: pkg.module, format: 'es' }, - ], - plugins: [ - // Compile to commonjs and bundle - commonjs() - ], - }, - { - input: './src/utils.js', - output: [ - { - file: 'dist/utils.js', - format: 'cjs', - globals: { - Cypress: 'cypress', - }, - }, - { file: 'dist/utils.mjs', format: 'es' }, - ], - plugins: [ - // Compile to commonjs and bundle - commonjs() - ], - }, - { - input: './src/test-runner.js', - output: [ - { - file: 'dist/test-runner.js', - format: 'cjs', - globals: { - Cypress: 'cypress', - }, - }, - { file: 'dist/test-runner.mjs', format: 'es' }, - ], - plugins: [ - // Compile to commonjs and bundle - commonjs() - ], -} -]; - -module.exports = config; diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/buttons.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/buttons.js deleted file mode 100644 index 0ca16a2fa6e..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/buttons.js +++ /dev/null @@ -1,25 +0,0 @@ -Cypress.Commands.add('btnCreateClick', function() { - cy.get('.btn.create').click(); -}); - -Cypress.Commands.add('btnSaveClick', function() { - cy.get('.btn.save').click(); -}); -Cypress.Commands.add('btnSaveContinueClick', function() { - cy.get('.dropdown-item.save-continue').click(); -}); - -Cypress.Commands.add('btnCancelClick', function() { - cy.get('.btn.cancel').click(); -}); - -Cypress.Commands.add('btnPublishClick', function() { - cy.get('.btn.public').click(); -}); -Cypress.Commands.add('btnPublishContinueClick', function() { - cy.get('.dropdown-item.publish-continue').click(); -}); - -Cypress.Commands.add('btnModalOkClick', function() { - cy.get("#modalOkButton").click(); -}); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/configuration.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/configuration.js deleted file mode 100644 index c06a5f58508..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/configuration.js +++ /dev/null @@ -1,9 +0,0 @@ -Cypress.Commands.add("setPageSize", ({prefix = ""}, size) => { - cy.visit(`${prefix}/Admin/Settings/general`); - cy.get('#ISite_PageSize') - .clear() - .type(size); - cy.btnSaveClick(); - // wait until the success message is displayed - cy.get('.message-success'); -}); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/cySelectors.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/cySelectors.js deleted file mode 100644 index b2791e780c0..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/cySelectors.js +++ /dev/null @@ -1,20 +0,0 @@ -function byCy(id, exact) { - if (exact) { - return `[data-cy="${id}"]`; - } - return `[data-cy^="${id}"]`; -} - -Cypress.Commands.add('getByCy', (selector, exact = false) => { - return cy.get(byCy(selector, exact)); -}); - -Cypress.Commands.add( - 'findByCy', - {prevSubject: 'optional'}, - (subject, selector, exact = false) => { - return subject - ? cy.wrap(subject).find(byCy(selector, exact)) - : cy.find(byCy(selector, exact)); - }, -); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/features.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/features.js deleted file mode 100644 index 003e0b2ee91..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/features.js +++ /dev/null @@ -1,10 +0,0 @@ -Cypress.Commands.add("enableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-enable-${featureName}`).click(); -}); - -Cypress.Commands.add("diableFeature", ({ prefix }, featureName) => { - cy.visit(`${prefix}/Admin/Features`); - cy.get(`#btn-diable-${featureName}`).click(); -}); - diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/index.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/index.js deleted file mode 100644 index 93d7bffa91f..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import './tenants'; -import './recipe'; -import './cySelectors'; -import './configuration'; -import './features'; -import './urls'; -import './buttons'; - diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/recipe.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/recipe.js deleted file mode 100644 index db57037c8db..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/recipe.js +++ /dev/null @@ -1,18 +0,0 @@ -Cypress.Commands.add("runRecipe", ({ prefix }, recipeName) => { - cy.visit(`${prefix}/Admin/Recipes`); - cy.get(`#btn-run-${recipeName}`).click(); - cy.btnModalOkClick(); -}); - -Cypress.Commands.add("uploadRecipeJson", ({ prefix }, fixturePath) => { - cy.fixture(fixturePath).then((data) => { - cy.visit(`${prefix}/Admin/DeploymentPlan/Import/Json`); - cy.get('.CodeMirror').should('be.visible'); - cy.get("body").then($body => { - $body.find(".CodeMirror")[0].CodeMirror.setValue(JSON.stringify(data)); - }); - cy.get('.ta-content > form').submit(); - // make sure the message-success alert is displayed - cy.get('.message-success').should('contain', "Recipe imported"); - }); - }); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/tenants.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/tenants.js deleted file mode 100644 index 11bc7a87349..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/tenants.js +++ /dev/null @@ -1,63 +0,0 @@ -Cypress.Commands.add("login", function({ prefix = ""}={}) { - const config = Cypress.config('orchard'); - cy.visit(`${prefix}/login`); - cy.get("#LoginForm_UserName").type(config.username); - cy.get("#LoginForm_Password").type(config.password); - cy.get("#LoginForm_UserName").closest('form').submit(); -}); - -Cypress.Commands.add("visitTenantSetupPage", ({ name }) => { - cy.visit("/Admin/Tenants"); - cy.get(`#btn-setup-${name}`).click(); -}); - -Cypress.Commands.add("siteSetup", ({ name, setupRecipe }) => { - const config = Cypress.config('orchard'); - cy.get("#SiteName").type(name); - cy.get("body").then($body => { - const elem = $body.find("#RecipeName"); - if (elem) { - elem.val(setupRecipe); - } - const db = $body.find("#DatabaseProvider"); - if(db.length > 0 && db.val() == "") { - db.val("Sqlite"); - } - }); - cy.get("#UserName").type(config.username); - cy.get("#Email").type(config.email); - cy.get("#Password").type(config.password); - cy.get("#PasswordConfirmation").type(config.password); - cy.get("#SubmitButton").click(); -}); -Cypress.Commands.add('newTenant', function(tenantInfo) { - cy.login(); - cy.createTenant(tenantInfo); - cy.visitTenantSetupPage(tenantInfo); - cy.siteSetup(tenantInfo); -}); - -Cypress.Commands.add("createTenant", ({ name, prefix, setupRecipe, description }) => { - // We create tenants on the SaaS tenant - cy.visit("/Admin/Tenants"); - cy.btnCreateClick(); - cy.get("#Name").type(name, {force:true}); - cy.get("#Description").type(`Recipe: ${setupRecipe}. ${description || ''}`, {force:true}); - cy.get("#RequestUrlPrefix").type(prefix, {force:true}); - cy.get("#RecipeName").select(setupRecipe); - cy.get("body").then($body => { - const db = $body.find("#DatabaseProvider"); - // if a database provider is already specified by an environment variable.. leave it as is - // this assumes that if you set the provider, you also set the connectionString - if (db.length > 0 && db.val() == "") { - db.val('Sqlite'); - } else { - //set the tablePrefix to the name. - const prefix = $body.find("#TablePrefix"); - if(prefix.length > 0){ - prefix.val(name); - } - } - }); - cy.btnCreateClick(); -}); diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/test-runner.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/test-runner.js deleted file mode 100644 index 8f0db2b723d..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/test-runner.js +++ /dev/null @@ -1,105 +0,0 @@ -// This module was originally build by the OrchardCore team -const child_process = require("child_process"); -const fs = require("fs-extra"); -const path = require("path"); - -global.log = function (msg) { - let now = new Date().toLocaleTimeString(); - console.log(`[${now}] ${msg}\n`); - - if (msg.indexOf("Exception") >= 0) { - throw new Error("An exception was detected"); - } - - if (msg.indexOf("fail:") == 0) { - throw new Error("An error was logged"); - } -}; - -// Build the dotnet application in release mode -export function build(dir, dotnetVersion) { - global.log("Building ..."); - child_process.spawnSync("dotnet", ["build", "-c", "Release", "-f", dotnetVersion], { cwd: dir }); -} - -// destructive action that deletes the App_Data folder -export function deleteDirectory(dir) { - fs.removeSync(dir); - global.log(`${dir} deleted`); -} - -// Copy the migrations recipe. -function copyMigrationsRecipeFile(dir) { - - const recipeFilePath = 'Recipes/migrations.recipe.json'; - - if (!fs.existsSync(`./${recipeFilePath}`) || fs.existsSync(`${dir}/${recipeFilePath}`)) { - return; - } - - if (!fs.existsSync(`${dir}/Recipes`)) { - fs.mkdirSync(`${dir}/Recipes`); - } - - fs.copyFile(`./${recipeFilePath}`, `${dir}/${recipeFilePath}`); - global.log(`migrations recipe copied to ${dir}/Recipes`); -} - -// Host the dotnet application, does not rebuild -export function host(dir, assembly, { appDataLocation = './App_Data', dotnetVersion = 'net10.0' } = {}) { - if (fs.existsSync(path.join(dir, `bin/Release/${dotnetVersion}/`, assembly))) { - global.log("Application already built, skipping build"); - } else { - build(dir, dotnetVersion); - } - global.log("Starting application ..."); - - const ocEnv = {}; - ocEnv["ORCHARD_APP_DATA"] = appDataLocation; - - let server = child_process.spawn( - "dotnet", - [`bin/Release/${dotnetVersion}/` + assembly], - { cwd: dir, env: { ...process.env, ...ocEnv } } - ); - - server.stdout.on("data", data => { - global.log(data); - }); - - server.stderr.on("data", data => { - global.log(`stderr: ${data}`); - }); - - server.on("close", code => { - global.log(`Server process exited with code ${code}`); - }); - return server; -} - -// combines the functions above, useful when triggering tests from CI -export function e2e(dir, assembly, { dotnetVersion = 'net10.0' } = {}) { - copyMigrationsRecipeFile(dir); - deleteDirectory(path.join(dir, "App_Data_Tests")); - var server = host(dir, assembly, { appDataLocation: "./App_Data_Tests", dotnetVersion }); - - // Wait for server to start up before launching Cypress - global.log("Waiting for server to start..."); - setTimeout(() => { - let test = child_process.exec("npx cypress run"); - test.stdout.on("data", data => { - console.log(data); - }); - - test.stderr.on("data", data => { - console.log(`stderr: ${data}`); - }); - - test.on("close", code => { - console.log(`Cypress process exited with code ${code}`); - server.kill("SIGINT"); - process.exit(code); - }); - }, 10000); // Wait 10 seconds for server to start -} - diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/urls.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/urls.js deleted file mode 100644 index 9aa374cbb7c..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/urls.js +++ /dev/null @@ -1,4 +0,0 @@ -Cypress.Commands.add("visitContentPage", ({ prefix }, contentItemId) => { - cy.visit(`${prefix}/Contents/ContentItems/${contentItemId}`); -}); - diff --git a/test/OrchardCore.Tests.Functional/cypress-commands/src/utils.js b/test/OrchardCore.Tests.Functional/cypress-commands/src/utils.js deleted file mode 100644 index 9e480756675..00000000000 --- a/test/OrchardCore.Tests.Functional/cypress-commands/src/utils.js +++ /dev/null @@ -1,17 +0,0 @@ -// https://stackoverflow.com/questions/105034/how-to-create-guid-uuid - -function generateUniqueName() { - var date = new Date(); - var today = new Date(date.getFullYear(), date.getMonth(), date.getDate()); - return 't' + (date - today).toString(32); -} - -export function generateTenantInfo(setupRecipeName, description) { - var uniqueName = generateUniqueName(); - return { - name: uniqueName, - prefix: uniqueName, - setupRecipe: setupRecipeName, - description - } -} diff --git a/test/OrchardCore.Tests.Functional/mvc-tests/cypress.json b/test/OrchardCore.Tests.Functional/mvc-tests/cypress.json deleted file mode 100644 index c4043d1fa53..00000000000 --- a/test/OrchardCore.Tests.Functional/mvc-tests/cypress.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "baseUrl": "http://localhost:5000", - "video": false -} diff --git a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/integration/mvc-test.js b/test/OrchardCore.Tests.Functional/mvc-tests/cypress/integration/mvc-test.js deleted file mode 100644 index ee7cd240608..00000000000 --- a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/integration/mvc-test.js +++ /dev/null @@ -1,9 +0,0 @@ -/// - -describe('MVC Tests', function () { - - it('should display "Hello World"', function(){ - cy.visit('/') - cy.get('body').should('contain.text', 'Hello World'); - }) -}); diff --git a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/plugins/index.js b/test/OrchardCore.Tests.Functional/mvc-tests/cypress/plugins/index.js deleted file mode 100644 index fd170fba691..00000000000 --- a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/plugins/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/support/commands.js b/test/OrchardCore.Tests.Functional/mvc-tests/cypress/support/commands.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/support/index.js b/test/OrchardCore.Tests.Functional/mvc-tests/cypress/support/index.js deleted file mode 100644 index d68db96df26..00000000000 --- a/test/OrchardCore.Tests.Functional/mvc-tests/cypress/support/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/test/OrchardCore.Tests.Functional/package-lock.json b/test/OrchardCore.Tests.Functional/package-lock.json deleted file mode 100644 index 0a8da27913c..00000000000 --- a/test/OrchardCore.Tests.Functional/package-lock.json +++ /dev/null @@ -1,4232 +0,0 @@ -{ - "name": "@orchardcore/tests-functional", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "cypress": "^9.6.1", - "cypress-orchardcore": "file:cypress-commands", - "faker": "^6.6.6", - "fs-extra": "^10.1.0" - } - }, - "cypress-commands": { - "name": "cypress-orchardcore", - "version": "0.4.7", - "dev": true, - "license": "MIT", - "dependencies": { - "fs-extra": "^10.0.1" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.0", - "rollup": "^4.22.4" - } - }, - "node_modules/@cypress/request": { - "version": "2.88.12", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.12.tgz", - "integrity": "sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "http-signature": "~1.3.6", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "~6.10.3", - "safe-buffer": "^5.1.2", - "tough-cookie": "^4.1.3", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "node_modules/@cypress/xvfb/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/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", - "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.1.1", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-commonjs/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "node_modules/@rollup/pluginutils/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "node_modules/@types/node": { - "version": "14.17.32", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.32.tgz", - "integrity": "sha512-JcII3D5/OapPGx+eJ+Ik1SQGyt6WvuqdRfh9jUwL6/iHGjmyOriBDciBUu7lEIBTL2ijxwrR70WUnw5AEDmFvQ==", - "dev": true - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true - }, - "node_modules/@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", - "dev": true - }, - "node_modules/@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "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": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/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/check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "colors": "1.4.0" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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": ">=7.0.0" - } - }, - "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/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cypress": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", - "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@cypress/request": "^2.88.10", - "@cypress/xvfb": "^1.2.4", - "@types/node": "^14.14.31", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.6.0", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "cli-cursor": "^3.1.0", - "cli-table3": "~0.6.1", - "commander": "^5.1.0", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "eventemitter2": "^6.4.3", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "is-ci": "^3.0.0", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.6", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.3.2", - "supports-color": "^8.1.1", - "tmp": "~0.2.1", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "bin": { - "cypress": "bin/cypress" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/cypress-orchardcore": { - "resolved": "cypress-commands", - "link": true - }, - "node_modules/cypress/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/dayjs": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", - "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "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/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==", - "dev": true - }, - "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "dependencies": { - "pify": "^2.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/faker": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz", - "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==", - "dev": true - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "dependencies": { - "async": "^3.2.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, - "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/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", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-signature": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", - "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.14.1" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "node_modules/lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", - "dev": true, - "engines": { - "node": "> 0.8" - } - }, - "node_modules/listr2": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.1.tgz", - "integrity": "sha512-pk4YBDA2cxtpM8iLHbz6oEsfZieJKHf6Pt19NlKaHZZVpqHyVs/Wqr7RfBBCeAFCJchGO7WQHVkUPZTvJMHk8w==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - } - }, - "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.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "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", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", - "dev": true - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", - "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "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", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", - "dev": true, - "dependencies": { - "throttleit": "^1.0.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", - "fsevents": "~2.3.2" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "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", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "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.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - }, - "dependencies": { - "@cypress/request": { - "version": "2.88.12", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.12.tgz", - "integrity": "sha512-tOn+0mDZxASFM+cuAP9szGUGPI1HwWVSvdzm7V4cCsPdFTx6qMj29CwaQmRAMIEhORIUBFBsYROYJcveK4uOjA==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "http-signature": "~1.3.6", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "~6.10.3", - "safe-buffer": "^5.1.2", - "tough-cookie": "^4.1.3", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - } - }, - "@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - }, - "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" - } - } - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, - "@rollup/plugin-commonjs": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz", - "integrity": "sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.1.1", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^2.3.1" - }, - "dependencies": { - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - } - } - }, - "@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "dependencies": { - "@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - } - } - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", - "dev": true, - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", - "dev": true, - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", - "dev": true, - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", - "dev": true, - "optional": true - }, - "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "@types/node": { - "version": "14.17.32", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.32.tgz", - "integrity": "sha512-JcII3D5/OapPGx+eJ+Ik1SQGyt6WvuqdRfh9jUwL6/iHGjmyOriBDciBUu7lEIBTL2ijxwrR70WUnw5AEDmFvQ==", - "dev": true - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true - }, - "@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", - "dev": true - }, - "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "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" - } - }, - "arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "dev": true - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "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" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", - "dev": true - }, - "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "dev": true, - "requires": { - "colors": "1.4.0", - "string-width": "^4.2.0" - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.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 - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "optional": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "cypress": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-9.7.0.tgz", - "integrity": "sha512-+1EE1nuuuwIt/N1KXRR2iWHU+OiIt7H28jJDyyI4tiUftId/DrXYEwoDa5+kH2pki1zxnA0r6HrUGHV5eLbF5Q==", - "dev": true, - "requires": { - "@cypress/request": "^2.88.10", - "@cypress/xvfb": "^1.2.4", - "@types/node": "^14.14.31", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.6.0", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "cli-cursor": "^3.1.0", - "cli-table3": "~0.6.1", - "commander": "^5.1.0", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.2", - "enquirer": "^2.3.6", - "eventemitter2": "^6.4.3", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "is-ci": "^3.0.0", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.6", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.3.2", - "supports-color": "^8.1.1", - "tmp": "~0.2.1", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - } - } - }, - "cypress-orchardcore": { - "version": "file:cypress-commands", - "requires": { - "@rollup/plugin-commonjs": "^28.0.0", - "fs-extra": "^10.0.1", - "rollup": "^4.22.4" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "dayjs": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", - "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "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", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.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 - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "eventemitter2": { - "version": "6.4.5", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz", - "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==", - "dev": true - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "dev": true, - "requires": { - "pify": "^2.2.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "faker": { - "version": "6.6.6", - "resolved": "https://registry.npmjs.org/faker/-/faker-6.6.6.tgz", - "integrity": "sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg==", - "dev": true - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", - "dev": true, - "requires": {} - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "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-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "requires": { - "async": "^3.2.0" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - } - }, - "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.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "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 - }, - "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", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "http-signature": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", - "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.14.1" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "requires": { - "@types/estree": "*" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", - "dev": true - }, - "listr2": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.13.1.tgz", - "integrity": "sha512-pk4YBDA2cxtpM8iLHbz6oEsfZieJKHf6Pt19NlKaHZZVpqHyVs/Wqr7RfBBCeAFCJchGO7WQHVkUPZTvJMHk8w==", - "dev": true, - "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rxjs": "^6.6.7", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dev": true, - "requires": { - "mime-db": "1.51.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", - "dev": true - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "optional": true, - "peer": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "qs": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", - "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", - "dev": true, - "requires": { - "throttleit": "^1.0.0" - } - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, - "requires": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", - "@types/estree": "1.0.5", - "fsevents": "~2.3.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true - }, - "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", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "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.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true - }, - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } -} diff --git a/test/OrchardCore.Tests.Functional/package.json b/test/OrchardCore.Tests.Functional/package.json deleted file mode 100644 index 9a07b887de0..00000000000 --- a/test/OrchardCore.Tests.Functional/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "@orchardcore/tests-functional", - "devDependencies": { - "cypress": "^9.6.1", - "cypress-orchardcore": "file:cypress-commands", - "faker": "^6.6.6", - "fs-extra": "^10.1.0" - }, - "scripts": { - "mvc:test": "cd mvc-tests && node -e \"require('cypress-orchardcore/dist/test-runner').e2e('../../../src/OrchardCore.Mvc.Web', 'OrchardCore.Mvc.Web.dll')\"", - "mvc:cypress": "cd mvc-tests && cypress open", - "cms:build": "node -e \"require('cypress-orchardcore/dist/test-runner').build('../../src/OrchardCore.Cms.Web')\"", - "cms:host": "node -e \"require('cypress-orchardcore/dist/test-runner').host('../../src/OrchardCore.Cms.Web', 'OrchardCore.Cms.Web.dll')\"", - "cms:test": "cd cms-tests && node -e \"require('cypress-orchardcore/dist/test-runner').e2e('../../../src/OrchardCore.Cms.Web', 'OrchardCore.Cms.Web.dll')\"", - "cms:cypress": "cd cms-tests && cypress open", - "gen:blog": "node -e \"require('./test_generator').generateBlogData()\"" - } -} diff --git a/test/OrchardCore.Tests.Functional/run-db-tests.ps1 b/test/OrchardCore.Tests.Functional/run-db-tests.ps1 new file mode 100644 index 00000000000..fa7103df59f --- /dev/null +++ b/test/OrchardCore.Tests.Functional/run-db-tests.ps1 @@ -0,0 +1,151 @@ +# Usage: +# .\run-db-tests.ps1 postgres # Run CMS tests against PostgreSQL +# .\run-db-tests.ps1 mysql # Run CMS tests against MySQL +# .\run-db-tests.ps1 mssql # Run CMS tests against SQL Server +# .\run-db-tests.ps1 sqlite # Run CMS tests against SQLite (no container) +# .\run-db-tests.ps1 all # Run against all databases sequentially +# .\run-db-tests.ps1 cleanup # Remove all test containers + +param( + [Parameter(Mandatory=$true, Position=0)] + [ValidateSet('postgres','mysql','mssql','sqlite','all','cleanup')] + [string]$Target +) + +$ErrorActionPreference = 'Stop' + +# Force English locale so test assertions match regardless of host language. +$env:LANG = 'en_US.UTF-8' +$env:LC_ALL = 'en_US.UTF-8' + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$Project = Join-Path $ScriptDir 'OrchardCore.Tests.Functional.csproj' + +function Invoke-Cleanup { + Write-Host "Cleaning up test containers..." + docker rm -f oc-test-postgres oc-test-mysql oc-test-mssql 2>$null +} + +function Invoke-Build { + Write-Host "Building..." + dotnet build -c Release $Project + + $BuildDir = Join-Path $ScriptDir 'bin\Release\net10.0' + $PlaywrightDll = Join-Path $BuildDir 'Microsoft.Playwright.dll' + if (Test-Path $PlaywrightDll) { + Write-Host "Installing Playwright browsers..." + $RuntimeConfig = Join-Path $BuildDir 'OrchardCore.Tests.Functional.runtimeconfig.json' + dotnet exec --runtimeconfig $RuntimeConfig $PlaywrightDll install chromium + } +} + +function Invoke-Tests { + param([string]$ConnString, [string]$Provider) + + Write-Host "" + Write-Host "=========================================" + Write-Host "Running CMS tests with $Provider" + Write-Host "=========================================" + + $env:ASPNETCORE_ENVIRONMENT = 'Production' + $env:OrchardCore__ConnectionString = $ConnString + $env:OrchardCore__DatabaseProvider = $Provider + try { + dotnet test --project $Project -c Release --no-build --filter-class "*Cms*" + } finally { + Remove-Item Env:\ASPNETCORE_ENVIRONMENT -ErrorAction SilentlyContinue + Remove-Item Env:\OrchardCore__ConnectionString -ErrorAction SilentlyContinue + Remove-Item Env:\OrchardCore__DatabaseProvider -ErrorAction SilentlyContinue + } +} + +function Invoke-SqliteTests { + Write-Host "" + Write-Host "=========================================" + Write-Host "Running CMS tests with SQLite" + Write-Host "=========================================" + + $env:ASPNETCORE_ENVIRONMENT = 'Production' + try { + dotnet test --project $Project -c Release --no-build --filter-class "*Cms*" + } finally { + Remove-Item Env:\ASPNETCORE_ENVIRONMENT -ErrorAction SilentlyContinue + } +} + +function Start-Postgres { + docker rm -f oc-test-postgres 2>$null + Write-Host "Starting PostgreSQL..." + docker run -d --name oc-test-postgres -p 5432:5432 ` + -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=admin -e POSTGRES_DB=app ` + --health-cmd="pg_isready" --health-interval=2s --health-timeout=5s --health-retries=10 ` + postgres:11 + + Write-Host "Waiting for PostgreSQL to be ready..." + while ((docker inspect --format='{{.State.Health.Status}}' oc-test-postgres 2>$null) -notmatch 'healthy') { + Start-Sleep -Seconds 1 + } + Write-Host "PostgreSQL is ready." +} + +function Start-MySQL { + docker rm -f oc-test-mysql 2>$null + Write-Host "Starting MySQL..." + docker run -d --name oc-test-mysql -p 3306:3306 ` + -e MYSQL_DATABASE=test -e MYSQL_ROOT_PASSWORD=test123 ` + --health-cmd="mysqladmin ping -h localhost" --health-interval=2s --health-timeout=5s --health-retries=15 ` + mysql:8 + + Write-Host "Waiting for MySQL to be ready..." + while ((docker inspect --format='{{.State.Health.Status}}' oc-test-mysql 2>$null) -notmatch 'healthy') { + Start-Sleep -Seconds 1 + } + Write-Host "MySQL is ready." +} + +function Start-MsSql { + docker rm -f oc-test-mssql 2>$null + Write-Host "Starting SQL Server..." + docker run -d --name oc-test-mssql -p 1433:1433 ` + -e ACCEPT_EULA=Y -e "MSSQL_SA_PASSWORD=Password12!" ` + mcr.microsoft.com/mssql/server:2019-latest + + Write-Host "Waiting for SQL Server to be ready..." + Start-Sleep -Seconds 10 + Write-Host "SQL Server is ready." +} + +switch ($Target) { + 'postgres' { + Invoke-Build + Start-Postgres + Invoke-Tests 'User ID=postgres;Password=admin;Host=localhost;Port=5432;Database=app;' 'Postgres' + } + 'mysql' { + Invoke-Build + Start-MySQL + Invoke-Tests 'server=localhost;uid=root;pwd=test123;database=test' 'MySql' + } + 'mssql' { + Invoke-Build + Start-MsSql + Invoke-Tests 'Server=localhost;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False' 'SqlConnection' + } + 'sqlite' { + Invoke-Build + Invoke-SqliteTests + } + 'all' { + Invoke-Build + Invoke-SqliteTests + Start-Postgres + Invoke-Tests 'User ID=postgres;Password=admin;Host=localhost;Port=5432;Database=app;' 'Postgres' + Start-MySQL + Invoke-Tests 'server=localhost;uid=root;pwd=test123;database=test' 'MySql' + Start-MsSql + Invoke-Tests 'Server=localhost;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False' 'SqlConnection' + } + 'cleanup' { + Invoke-Cleanup + } +} diff --git a/test/OrchardCore.Tests.Functional/run-db-tests.sh b/test/OrchardCore.Tests.Functional/run-db-tests.sh new file mode 100755 index 00000000000..278827ab6e0 --- /dev/null +++ b/test/OrchardCore.Tests.Functional/run-db-tests.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Force English locale so test assertions match regardless of host language. +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +# Usage: +# ./run-db-tests.sh postgres # Run CMS tests against PostgreSQL +# ./run-db-tests.sh mysql # Run CMS tests against MySQL +# ./run-db-tests.sh mssql # Run CMS tests against SQL Server +# ./run-db-tests.sh sqlite # Run CMS tests against SQLite (no container) +# ./run-db-tests.sh all # Run against all databases sequentially +# ./run-db-tests.sh cleanup # Remove all test containers + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +PROJECT="$SCRIPT_DIR/OrchardCore.Tests.Functional.csproj" + +cleanup() { + echo "Cleaning up test containers..." + docker rm -f oc-test-postgres oc-test-mysql oc-test-mssql 2>/dev/null || true +} + +build() { + echo "Building..." + dotnet build -c Release "$PROJECT" + + local build_dir="$SCRIPT_DIR/bin/Release/net10.0" + local playwright_dll="$build_dir/Microsoft.Playwright.dll" + if [ -f "$playwright_dll" ]; then + echo "Installing Playwright browsers..." + dotnet exec --runtimeconfig "$build_dir/OrchardCore.Tests.Functional.runtimeconfig.json" "$playwright_dll" install chromium + fi +} + +run_tests() { + local conn="$1" + local provider="$2" + + echo "" + echo "=========================================" + echo "Running CMS tests with $provider" + echo "=========================================" + + ASPNETCORE_ENVIRONMENT=Production \ + OrchardCore__ConnectionString="$conn" \ + OrchardCore__DatabaseProvider="$provider" \ + dotnet test --project "$PROJECT" -c Release --no-build --filter-class "*Cms*" +} + +run_sqlite() { + echo "" + echo "=========================================" + echo "Running CMS tests with SQLite" + echo "=========================================" + + ASPNETCORE_ENVIRONMENT=Production \ + dotnet test --project "$PROJECT" -c Release --no-build --filter-class "*Cms*" +} + +start_postgres() { + docker rm -f oc-test-postgres 2>/dev/null || true + echo "Starting PostgreSQL..." + docker run -d --name oc-test-postgres -p 5432:5432 \ + -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=admin -e POSTGRES_DB=app \ + --health-cmd="pg_isready" --health-interval=2s --health-timeout=5s --health-retries=10 \ + postgres:11 + + echo "Waiting for PostgreSQL to be ready..." + until docker inspect --format='{{.State.Health.Status}}' oc-test-postgres 2>/dev/null | grep -q healthy; do + sleep 1 + done + echo "PostgreSQL is ready." +} + +start_mysql() { + docker rm -f oc-test-mysql 2>/dev/null || true + echo "Starting MySQL..." + docker run -d --name oc-test-mysql -p 3306:3306 \ + -e MYSQL_DATABASE=test -e MYSQL_ROOT_PASSWORD=test123 \ + --health-cmd="mysqladmin ping -h localhost" --health-interval=2s --health-timeout=5s --health-retries=15 \ + mysql:8 + + echo "Waiting for MySQL to be ready..." + until docker inspect --format='{{.State.Health.Status}}' oc-test-mysql 2>/dev/null | grep -q healthy; do + sleep 1 + done + echo "MySQL is ready." +} + +start_mssql() { + docker rm -f oc-test-mssql 2>/dev/null || true + echo "Starting SQL Server..." + docker run -d --name oc-test-mssql -p 1433:1433 \ + -e ACCEPT_EULA=Y -e MSSQL_SA_PASSWORD='Password12!' \ + mcr.microsoft.com/mssql/server:2019-latest + + echo "Waiting for SQL Server to be ready..." + sleep 10 + echo "SQL Server is ready." +} + +case "${1:-}" in + postgres) + build + start_postgres + run_tests "User ID=postgres;Password=admin;Host=localhost;Port=5432;Database=app;" "Postgres" + ;; + mysql) + build + start_mysql + run_tests "server=localhost;uid=root;pwd=test123;database=test" "MySql" + ;; + mssql) + build + start_mssql + run_tests "Server=localhost;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False" "SqlConnection" + ;; + sqlite) + build + run_sqlite + ;; + all) + build + run_sqlite + start_postgres + run_tests "User ID=postgres;Password=admin;Host=localhost;Port=5432;Database=app;" "Postgres" + start_mysql + run_tests "server=localhost;uid=root;pwd=test123;database=test" "MySql" + start_mssql + run_tests "Server=localhost;Database=tempdb;User Id=sa;Password=Password12!;Encrypt=False" "SqlConnection" + ;; + cleanup) + cleanup + ;; + *) + echo "Usage: $0 {postgres|mysql|mssql|sqlite|all|cleanup}" + exit 1 + ;; +esac diff --git a/test/OrchardCore.Tests.Functional/test_generator.js b/test/OrchardCore.Tests.Functional/test_generator.js deleted file mode 100644 index 11a5df5825b..00000000000 --- a/test/OrchardCore.Tests.Functional/test_generator.js +++ /dev/null @@ -1,19 +0,0 @@ -const faker = require('faker'); -const fs = require('fs'); - -module.exports = { - generateBlogData: (count = 10) => { - let data = []; - for (let i = 0; i < count; i++) { - var name = faker.random.uuid(); - var text = faker.lorem.text(); - - data.push({ - name, - text - }); - } - - fs.writeFileSync('./cms-tests/cypress/fixtures/blog-posts.json', JSON.stringify(data, null, 4)); - } -};