diff --git a/.env.example b/.env.example index da38ca1c0b..afc4dc09a6 100644 --- a/.env.example +++ b/.env.example @@ -7,6 +7,7 @@ PHRASE_API_KEY_DEV= # [Optional] Mudita Center Server URL to access to external services via proxy MUDITA_CENTER_SERVER_URL= +MUDITA_CENTER_SERVER_V2_URL= # [Optional] Rollbar Token needed to connect user’s app with Rollbar account. ROLLBAR_TOKEN= @@ -55,20 +56,14 @@ FEATURE_TOGGLE_RELEASE_ENVIRONMENT= # [Optional] Enable Mudita Center prerelease feature. Disabled by default, set "1" to enable MUDITA_CENTER_PRERELEASE_ENABLED= -# [Optional] Path to your Google service account key file. Required for authentication with the Google Sheets API. -MATOMO_TO_GSHEET_KEYFILEPATH= - -# [Optional] The ID of the Google Sheet where Matomo data will be written. Found in the URL of your Google Sheet. -MATOMO_TO_GSHEET_SPREADSHEET_ID= - -# [Optional] The base URL for the Matomo API. This is where API requests will be sent to fetch analytics data. -MATOMO_TO_GSHEET_API_URL= +# [Optional] Set 1 run application with mock server +MOCK_SERVICE_ENABLED= -# [Optional] Your Matomo API token. Required for accessing data from your Matomo account through the API. -MATOMO_TO_GSHEET_TOKEN= +# [Optional] Enable shortcut for opening DevTools. Disabled by default, set "1" to enable +DEV_TOOLS_SHORTCUT_ENABLED= -# [Optional] The site ID for your website as registered in Matomo. Used to specify which site's data to fetch. -MATOMO_TO_GSHEET_SITE_ID= +# [Optional] Automatically open DevTools on startup. Disabled by default, set "1" to enable +DEV_TOOLS_AUTO_OPEN_ENABLED= -# [Optional] Set 1 run application with mock server -MOCK_SERVICE_ENABLED= +# [Optional] Allows to show unpublished content in Help. Disabled by default, set a secret token to enable +DEV_HELP_PREVIEW_TOKEN= diff --git a/.github/workflows/e2e-development.yml b/.github/workflows/e2e-development.yml index f12cf2cf71..fcbb2308ec 100644 --- a/.github/workflows/e2e-development.yml +++ b/.github/workflows/e2e-development.yml @@ -24,6 +24,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -54,4 +55,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y xvfb - npm run e2e:test:linux + npm run e2e:test:cicd:standalone diff --git a/.github/workflows/e2e-feature-branch.yml b/.github/workflows/e2e-feature-branch.yml index 86754f01e7..3961132b44 100644 --- a/.github/workflows/e2e-feature-branch.yml +++ b/.github/workflows/e2e-feature-branch.yml @@ -25,6 +25,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -55,4 +56,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y xvfb - npm run e2e:test:linux + npm run e2e:test:cicd:standalone diff --git a/.github/workflows/e2e-pre-production.yml b/.github/workflows/e2e-pre-production.yml index 2ab98c7cad..751c6b8648 100644 --- a/.github/workflows/e2e-pre-production.yml +++ b/.github/workflows/e2e-pre-production.yml @@ -26,6 +26,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -56,4 +57,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y xvfb - npm run e2e:test:linux + npm run e2e:test:cicd:standalone diff --git a/.github/workflows/e2e-production.yml b/.github/workflows/e2e-production.yml index 1eadf059a9..317bb4e03c 100644 --- a/.github/workflows/e2e-production.yml +++ b/.github/workflows/e2e-production.yml @@ -26,6 +26,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -56,4 +57,4 @@ jobs: run: | sudo apt-get update sudo apt-get install -y xvfb - npm run e2e:test:linux + npm run e2e:test:cicd:standalone diff --git a/.github/workflows/nexus-development.yml b/.github/workflows/nexus-development.yml index 9ad74baf69..a2a089d3d3 100644 --- a/.github/workflows/nexus-development.yml +++ b/.github/workflows/nexus-development.yml @@ -26,6 +26,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -43,6 +44,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" LOCALAPPDATA: "" shell: cmd run: | @@ -55,6 +57,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -72,6 +75,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" run: | printenv > .env - name: Setup Env for Linux @@ -81,6 +85,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -98,6 +103,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" run: | printenv > .env - name: Changing app version in packages.json for Linux diff --git a/.github/workflows/nexus-feature-branch.yml b/.github/workflows/nexus-feature-branch.yml index 224e482a63..05fe3307ab 100644 --- a/.github/workflows/nexus-feature-branch.yml +++ b/.github/workflows/nexus-feature-branch.yml @@ -26,6 +26,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -43,6 +44,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" LOCALAPPDATA: "" shell: cmd run: | @@ -55,6 +57,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -72,6 +75,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" run: | printenv > .env - name: Setup Env for Linux @@ -81,6 +85,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -98,6 +103,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" run: | printenv > .env - name: Changing app version in packages.json for Linux diff --git a/.github/workflows/nexus-mass-update.yml b/.github/workflows/nexus-mass-update.yml index d5b89e3a00..955b5abfdc 100644 --- a/.github/workflows/nexus-mass-update.yml +++ b/.github/workflows/nexus-mass-update.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -57,6 +58,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -83,6 +85,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} diff --git a/.github/workflows/nexus-mock-development.yml b/.github/workflows/nexus-mock-development.yml index dcfb923f8b..12a1f29e2a 100644 --- a/.github/workflows/nexus-mock-development.yml +++ b/.github/workflows/nexus-mock-development.yml @@ -26,6 +26,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -43,6 +44,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" LOCALAPPDATA: "" MOCK_SERVICE_ENABLED: "1" shell: cmd @@ -56,6 +58,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -73,6 +76,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" MOCK_SERVICE_ENABLED: "1" run: | printenv > .env @@ -83,6 +87,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -101,6 +106,7 @@ jobs: FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} MOCK_SERVICE_ENABLED: "1" + DEV_TOOLS_SHORTCUT_ENABLED: "1" run: | printenv > .env - name: Changing app version in packages.json for Linux diff --git a/.github/workflows/nexus-mock-pre-production.yml b/.github/workflows/nexus-mock-pre-production.yml index d32697c93a..6c357357fc 100644 --- a/.github/workflows/nexus-mock-pre-production.yml +++ b/.github/workflows/nexus-mock-pre-production.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -45,6 +46,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" LOCALAPPDATA: "" MOCK_SERVICE_ENABLED: "1" shell: cmd @@ -58,6 +60,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -75,6 +78,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" MOCK_SERVICE_ENABLED: "1" run: | printenv > .env diff --git a/.github/workflows/nexus-mock-production.yml b/.github/workflows/nexus-mock-production.yml index febb639529..a779823660 100644 --- a/.github/workflows/nexus-mock-production.yml +++ b/.github/workflows/nexus-mock-production.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -45,6 +46,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" LOCALAPPDATA: "" MOCK_SERVICE_ENABLED: "1" shell: cmd @@ -58,6 +60,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -75,6 +78,7 @@ jobs: DEV_DEVICE_LOGGER_ENABLED: ${{ secrets.DEV_DEVICE_LOGGER_ENABLED }} FEATURE_TOGGLE_RELEASE_ENVIRONMENT: ${{ secrets.FEATURE_TOGGLE_RELEASE_ENVIRONMENT }} MUDITA_CENTER_PRERELEASE_ENABLED: ${{ secrets.MUDITA_CENTER_PRERELEASE_ENABLED }} + DEV_TOOLS_SHORTCUT_ENABLED: "1" MOCK_SERVICE_ENABLED: "1" run: | printenv > .env diff --git a/.github/workflows/nexus-pre-production-latest.yml b/.github/workflows/nexus-pre-production-latest.yml index 1a960e842a..a1dbfe02aa 100644 --- a/.github/workflows/nexus-pre-production-latest.yml +++ b/.github/workflows/nexus-pre-production-latest.yml @@ -29,6 +29,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -58,6 +59,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -84,6 +86,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} diff --git a/.github/workflows/nexus-pre-production.yml b/.github/workflows/nexus-pre-production.yml index 2edea49b76..1373c40d7f 100644 --- a/.github/workflows/nexus-pre-production.yml +++ b/.github/workflows/nexus-pre-production.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -57,6 +58,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} diff --git a/.github/workflows/nexus-production-with-os-rc.yml b/.github/workflows/nexus-production-with-os-rc.yml index 8512e2a224..8742ecad96 100644 --- a/.github/workflows/nexus-production-with-os-rc.yml +++ b/.github/workflows/nexus-production-with-os-rc.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -57,6 +58,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -83,6 +85,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} diff --git a/.github/workflows/nexus-production.yml b/.github/workflows/nexus-production.yml index bac9443461..ed3e0b0423 100644 --- a/.github/workflows/nexus-production.yml +++ b/.github/workflows/nexus-production.yml @@ -28,6 +28,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} @@ -57,6 +58,7 @@ jobs: PHRASE_API_URL: ${{ secrets.PHRASE_API_URL }} PHRASE_API_KEY_DEV: ${{ secrets.PHRASE_API_KEY_DEV }} MUDITA_CENTER_SERVER_URL: ${{ secrets.MUDITA_CENTER_SERVER_URL }} + MUDITA_CENTER_SERVER_V2_URL: ${{ secrets.MUDITA_CENTER_SERVER_V2_URL }} ROLLBAR_TOKEN: ${{ secrets.ROLLBAR_TOKEN }} RELEASES_REPOSITORY_NAME: ${{ secrets.RELEASES_REPOSITORY_NAME }} PRERELEASES_ENABLED: ${{ secrets.PRERELEASES_ENABLED }} diff --git a/.stylelintrc.js b/.stylelintrc.js index c7f62c7eff..15c8f88fcc 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -2,6 +2,7 @@ module.exports = { extends: "@mudita/stylelint-config", rules: { "no-descending-specificity": null, + "value-no-vendor-prefix": null, "selector-type-no-unknown": [true, { ignoreTypes: ["$dummyValue"] }], }, } diff --git a/CHANGELOG.md b/CHANGELOG.md index c1050783b4..28f7b93eec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,29 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Here we write upgrading notes for brands. It's a team effort to make them as straightforward as possible. +## [2.4.0] - 2024-09-16 + +In this release, we have updated the Help section in the Mudita Center application. As of version 2.4.0, users can benefit from a refreshed help section with intuitive navigation. The article search functionality is also available. In addition, we have fixed two bugs occurring in our software. + +### Added + +- Added new Help section. + +### Changed + +- Removed old help functionality. +- Configured CMS for Help section in Mudita Center. + +### Fixed + +- Fixed not displayed newly added file on Manage Sounds. +- Fixed renaming of AppImage file when App Update. +- Fixed bypassing force update. +- Fixed broken layout in Contacts Search. +- Fixed ignoring of opening connected device Overview page, when News is current active tab. +- Fixed unexpected MDS behavior for Back and Forward mouse buttons. +- Fixed type in update checking failed window copy. + ## [2.3.0] - 2024-05-22 In this update, we have released the functionality of Multidevice support, the feature allows to support multiple Mudita devices in the Mudita Center application simultaneously without switching it. Moreover, we've successfully addressed 20 bugs across various features. diff --git a/libs/core/__mocks__/p-queue.ts b/__mocks__/p-queue.ts similarity index 100% rename from libs/core/__mocks__/p-queue.ts rename to __mocks__/p-queue.ts diff --git a/apps/mudita-center-e2e/package.json b/apps/mudita-center-e2e/package.json index 7d748dbd33..42d116da1d 100644 --- a/apps/mudita-center-e2e/package.json +++ b/apps/mudita-center-e2e/package.json @@ -18,7 +18,8 @@ }, "scripts": { "e2e:test": "npm run validate-test-paths && npx wdio run wdio.conf.ts", - "e2e:test:cicd": "npm run validate-test-paths && npx wdio run wdio.conf.ts --suite cicd", + "e2e:test:cicd:standalone": "npm run validate-test-paths && npx wdio run wdio.conf.ts --suite cicdStandalone", + "e2e:test:cicd:mock": "npm run validate-test-paths && npx wdio run wdio.conf.ts --suite cicdMock", "e2e:test:mock": "npm run validate-test-paths && npx wdio run wdio.conf.ts --suite mock", "e2e:test:standalone": "npm run validate-test-paths && npx wdio run wdio.conf.ts --suite standalone", "lint:typecheck:to-fix": "tsc --noEmit", diff --git a/apps/mudita-center-e2e/src/consts/regex-const.ts b/apps/mudita-center-e2e/src/consts/regex-const.ts index e5740a4bea..041cc83915 100644 --- a/apps/mudita-center-e2e/src/consts/regex-const.ts +++ b/apps/mudita-center-e2e/src/consts/regex-const.ts @@ -6,6 +6,8 @@ export const linkRegex: RegExp = /^(https?:\/\/)(mudita.com\/community|forum.mudita.com\/t).*$/ export const newsImageRegex: RegExp = /(^data:image;base64)/ +export const kompaktImageRegex: RegExp = /(^data:image\/png;base64)/ export const newsDateRegex: RegExp = /^(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(\s{1})([1-9]|[12][0-9]|3[01])(,{1})(\s{1})([2-9][0-9][0-9][0-9])$/ export const commentsRegex: RegExp = /^(\d+)(\s{1})(COMMENTS|COMMENT)$/ +export const kompaktImeiRegex: RegExp = /^[0-9]{1,15}$/ diff --git a/apps/mudita-center-e2e/src/helpers/tests.helper.ts b/apps/mudita-center-e2e/src/helpers/tests.helper.ts index b5277d67f7..9e9d8f74e5 100644 --- a/apps/mudita-center-e2e/src/helpers/tests.helper.ts +++ b/apps/mudita-center-e2e/src/helpers/tests.helper.ts @@ -10,8 +10,6 @@ class TestHelper { isLinux() { if (process.platform === "linux") { - console.log("CURRENT PLATFORM: " + process.platform) - console.log(process.platform + " = Test Skipped ") return true } return false diff --git a/apps/mudita-center-e2e/src/page-objects/about-kompakt.page.ts b/apps/mudita-center-e2e/src/page-objects/about-kompakt.page.ts new file mode 100644 index 0000000000..93838258fb --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/about-kompakt.page.ts @@ -0,0 +1,61 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +class AboutKompaktPage extends Page { + public get aboutHeader() { + return $("h3*=About your device") + } + + public get aboutSubtitle() { + return $("p*=Device details") + } + + public get backToOverviewIcon() { + return $('[data-testid="icon-ArrowLongLeft"]') + } + + public get backToOverviewLabel() { + return $('[data-testid="location"]') + } + + public get serialNumberLabel() { + return $('[data-testid="about-data-box-label-serial-number"]') + } + + public get serialNumberValue() { + return $('[data-testid="about-data-box-value-serial-number"]') + } + + public get imei1Label() { + return $('[data-testid="about-data-box-label-imei-(sim-slot-1)"]') + } + + public get imei1Value() { + return $('[data-testid="about-data-box-value-imei-(sim-slot-1)"]') + } + + public get imei2Label() { + return $('[data-testid="about-data-box-label-imei-(sim-slot-2)"]') + } + + public get imei2Value() { + return $('[data-testid="about-data-box-value-imei-(sim-slot-2)"]') + } + + public get sarLabel() { + return $('[data-testid="about-data-box-label-sar"]') + } + + public get sarButton() { + return $('[data-testid="button-text_sarmodal-button"]') + } + + public get sarHeader() { + return $("h3*=SAR") + } +} +export default new AboutKompaktPage() diff --git a/apps/mudita-center-e2e/src/page-objects/drawer.page.ts b/apps/mudita-center-e2e/src/page-objects/drawer.page.ts new file mode 100644 index 0000000000..ffe98fe835 --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/drawer.page.ts @@ -0,0 +1,29 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +export class DrawerPage extends Page { + public get deviceSelectDrawer() { + return $('[data-testid="device-select-drawer-content"]') + } + + public getDeviceOnDrawer(serialNumber: string) { + return $(`//*[@data-testid="drawer-device-wrapper-${serialNumber}"]`) + } + + public get deviceImageOnDrawer() { + return $('[data-testid="drawer-device-image"]') + } + public get drawerDeviceSerialNumber() { + return $$('[data-testid="drawer-device-serial-number-value"]') + } + + public get drawerDeviceName() { + return $$('[data-testid="drawer-device-type"]') + } +} + +export default new DrawerPage() diff --git a/apps/mudita-center-e2e/src/page-objects/mc-update-modal.page.ts b/apps/mudita-center-e2e/src/page-objects/mc-update-modal.page.ts index cb8715c3f0..823868ef96 100644 --- a/apps/mudita-center-e2e/src/page-objects/mc-update-modal.page.ts +++ b/apps/mudita-center-e2e/src/page-objects/mc-update-modal.page.ts @@ -27,7 +27,7 @@ class ModalPage extends Page { } get checkingFailedUpdateBody() { - return $("p*=Opps, something went wrong.") + return $("p*=Oops, something went wrong.") } } diff --git a/apps/mudita-center-e2e/src/page-objects/menu.page.ts b/apps/mudita-center-e2e/src/page-objects/menu.page.ts new file mode 100644 index 0000000000..db963382e8 --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/menu.page.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +export class Menu extends Page { + public get newsLink() { + return $(`//a[@href="#/news"]`) + } + + public get kompaktLabel() { + return $('[data-testid="Kompakt"]') + } + + public get overviewLink() { + return $(`//a[@href="#/generic/mc-overview"]`) + } + + public get muditaCenterLabel() { + return $('[data-testid="component.menuHeaderDesktopApp"]') + } + + public get settingsLink() { + return $(`//a[@href="#/settings"]`) + } + + public get helpLink() { + return $(`//a[@href="#/help"]`) + } +} + +export default new Menu() diff --git a/apps/mudita-center-e2e/src/page-objects/modal-app-update-error.page.ts b/apps/mudita-center-e2e/src/page-objects/modal-app-update-error.page.ts new file mode 100644 index 0000000000..9c6f61e2a5 --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/modal-app-update-error.page.ts @@ -0,0 +1,26 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +class ModalAppUpdateError extends Page { + public get infoIcon() { + return $('[data-testid="icon-Info"]') + } + + public get errorLabel() { + return $("h4*=Error") + } + + public get pleaseRestartParagraph() { + return $("p*=Please restart the app") + } + + public get closeButton() { + return $('[data-testid="close-bottom-button"]') + } +} + +export default new ModalAppUpdateError() diff --git a/apps/mudita-center-e2e/src/page-objects/modal-app-update-later.page.ts b/apps/mudita-center-e2e/src/page-objects/modal-app-update-later.page.ts new file mode 100644 index 0000000000..b2a19e37ee --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/modal-app-update-later.page.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +class ModalAppUpdateLater extends Page { + get modalHeader() { + return $('[data-testid="modal-title"]') + } + + get modalCloseButton() { + return $('[data-testid="close-modal-button"]') + } + + get appUpdateFlowContainer() { + return $('[data-testid="app-update-flow-container"]') + } + + get paragraphAvailableVersion() { + return $("h4*=Update Mudita Center to") + } + + get paragraphUpdateLaterPrivacyPolicy() { + return $( + "p*=To be able to fully use the application, please agree to the Privacy Policy and update Mudita Center." + ) + } + + get buttonUpdateLater() { + return $('[data-testid="close-bottom-button"]') + } + get buttonUpdate() { + return $('[data-testid="modal-action-button"]') + } +} + +export default new ModalAppUpdateLater() diff --git a/apps/mudita-center-e2e/src/page-objects/modal-app-update.page.ts b/apps/mudita-center-e2e/src/page-objects/modal-app-update.page.ts new file mode 100644 index 0000000000..d91a40c96b --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/modal-app-update.page.ts @@ -0,0 +1,52 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +class ModalAppUpdate extends Page { + get modalHeader() { + return $('[data-testid="modal-title"]') + } + + public get paragraphAvailableVersion() { + return $("h4*=Update Mudita Center to") + } + + public get paragraphCurrentVersion() { + return $("p*=Update it to use") + } + + public get paragraphPrivacyPolicy() { + return $( + "p*=Please accept the Privacy Policy to start updating Mudita Center." + ) + } + + public get linkPrivacyPolicy() { + return $("a=Privacy Policy") + } + + public get checkboxPrivacyPolicy() { + return $('[data-testid="privacy-policy-checkbox"]') + } + + public get buttonUpdate() { + return $('[data-testid="modal-action-button"]') + } + + public get paragraphUpdatingMuditaCenter() { + return $("h4*=Updating Mudita Center") + } + + public get spinnerLoader() { + return $('[data-testid="loader-spinner"]') + } + + public get paragraphPleaseWait() { + return $("p*=Please wait while Mudita Center is being updated.") + } +} + +export default new ModalAppUpdate() diff --git a/apps/mudita-center-e2e/src/page-objects/modal-sar.page.ts b/apps/mudita-center-e2e/src/page-objects/modal-sar.page.ts new file mode 100644 index 0000000000..3716cb1156 --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/modal-sar.page.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import Page from "./page" + +class AboutKompaktPage extends Page { + public get sarHeader() { + return $("h3*=SAR") + } + + public get modalCloseButton() { + return $('[data-testid="icon-close"]') + } +} +export default new AboutKompaktPage() diff --git a/apps/mudita-center-e2e/src/page-objects/overview-kompakt.page.ts b/apps/mudita-center-e2e/src/page-objects/overview-kompakt.page.ts index 606b247560..79ccf96a76 100644 --- a/apps/mudita-center-e2e/src/page-objects/overview-kompakt.page.ts +++ b/apps/mudita-center-e2e/src/page-objects/overview-kompakt.page.ts @@ -3,9 +3,81 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { ChainablePromiseElement } from "webdriverio" -import OverviewPage from "./overview.page" +import { OverviewPage } from "./overview.page" -class OverviewKompaktPage extends OverviewPage {} +class OverviewKompaktPage extends OverviewPage { + public get header() { + return $('[data-testid="location"]') + } + public get aboutYourDevice() { + return $('[data-testid="button-text_summary-about"]') + } + + public get sarInformationButtonKompakt() { + return $('[data-testid="button-text_sarmodal-button"]') + } + + public get sarInformationPopup() { + return $('[data-testid="button-text_sarmodal-button"]') + } + + public get sarInformationPopupCloseButton() { + return $('[data-testid="icon-close"]') + } + + public get backArrowButton() { + return $('[data-testid="icon-ArrowLongLeft"]') + } + + public get backupInfo() { + return $(`//div[@data-testid="block-box-backup"]//p`) + } + + public get serialNumberLabel() { + return $(`//div[@componentkey="summary-serial-number"]/p[1]`) + } + + public get serialNumberValue() { + return $(`//div[@componentkey="summary-serial-number"]/p[2]`) + } + + public get kompaktImage() { + return $('[data-testid="generic-view-image"]') + } + + public get kompaktSignalIcon() { + return $('[data-testid="icon-network-signal-2"]') + } + + public getStatusRow(rowIndex: number) { + return $( + `(//div[@data-testid="block-box-status"]/..//h4[@data-testid="icon-text"])[${rowIndex}]` + ) + } + + public get kompaktNetworkName() { + return this.getStatusRow(2) + } + + public get kompaktBatteryIcon() { + return $('//div[@data-testid="icon-battery-charging-5"]') + } + + public get kompaktBatteryLevelValue() { + return this.getStatusRow(1) + } + + public get kompaktSimCard1Subtext() { + return this.getStatusRow(2).$(`//*[@data-testid="icon-subtext"]`) + } + + public get kompaktOsVersion() { + return $('[data-testid="version"]') + } + + public get kompaktOsVersionLabel() { + return $('[data-testid="version-label"]') + } +} export default new OverviewKompaktPage() diff --git a/apps/mudita-center-e2e/src/page-objects/overview.page.ts b/apps/mudita-center-e2e/src/page-objects/overview.page.ts index 4aae54d5d6..ece1accf18 100644 --- a/apps/mudita-center-e2e/src/page-objects/overview.page.ts +++ b/apps/mudita-center-e2e/src/page-objects/overview.page.ts @@ -3,212 +3,147 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { ChainablePromiseElement } from "webdriverio" import Page from "./page" -class OverviewPage extends Page { - public get currentDeviceVersion(): ChainablePromiseElement< - Promise - > { +export class OverviewPage extends Page { + public get currentDeviceVersion() { return $("p*=MuditaOS") } - public get checkingForUpdateLoader(): ChainablePromiseElement< - Promise - > { + public get checkingForUpdateLoader() { return $("h4*=Checking for MuditaOS update...") } - public get downloadUpdateLoader(): ChainablePromiseElement< - Promise - > { + public get downloadUpdateLoader() { return $("*=Downloading update...") } - public get updateStatusLoader(): ChainablePromiseElement< - Promise - > { + public get updateStatusLoader() { return $("p*=Updating MuditaOS…") } - public get updateCompletedStatus(): ChainablePromiseElement< - Promise - > { + public get updateCompletedStatus() { return $("p*=Update completed!") } - public get checkForUpdateButton(): ChainablePromiseElement< - Promise - > { + public get checkForUpdateButton() { return $("button*=Check for updates") } - public get downloadUpdateNowButton(): ChainablePromiseElement< - Promise - > { + public get downloadUpdateNowButton() { return $('[data-testid="modal-action-button"]*=Download now') } - public get updateNowButton(): ChainablePromiseElement< - Promise - > { + public get updateNowButton() { return $('[data-testid="modal-action-button"]*=Update now') } - public get aboutYourPureButton(): ChainablePromiseElement< - Promise - > { + public get aboutYourPureButton() { return $("p*=About your Pure") } - public get checkSARInformationButton(): ChainablePromiseElement< - Promise - > { + public get checkSARInformationButton() { return $("p*=Check SAR information") } - public get sarWrapper(): ChainablePromiseElement< - Promise - > { + public get sarWrapper() { return $('[data-testid="sar-wrapper"]') } - public get backToOverviewButton(): ChainablePromiseElement< - Promise - > { + public get backToOverviewButton() { return $("p*=Back to Overview") } - public get createBackupButton(): ChainablePromiseElement< - Promise - > { - return $("p*=Create backup") + public get createBackupButton() { + return $('//button[@type="button" and .//span[text()="Create backup"]]') } - public get restoreBackupButton(): ChainablePromiseElement< - Promise - > { + public get restoreBackupButton() { return $("p*=Restore last backup") } - public get locationTextLabel(): ChainablePromiseElement< - Promise - > { + public get locationTextLabel() { return $('[data-testid="location"]') } - public get batteryLevel(): ChainablePromiseElement< - Promise - > { + public get batteryLevel() { return $('[data-testid="battery-level"]') } - public get fullBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get fullBatteryIcon() { return $('[data-testid="icon-FullBattery"]') } - public get veryHighBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get veryHighBatteryIcon() { return $('[data-testid="icon-VeryHighBattery"]') } - public get highBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get highBatteryIcon() { return $('[data-testid="icon-HighBattery"]') } - public get mediumBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get mediumBatteryIcon() { return $('[data-testid="icon-MediumBattery"]') } - public get lowBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get lowBatteryIcon() { return $('[data-testid="icon-LowBattery"]') } - public get veryLowBatteryIcon(): ChainablePromiseElement< - Promise - > { + public get veryLowBatteryIcon() { return $('[data-testid="icon-VeryLowBattery"]') } - public get noRangeIcon(): ChainablePromiseElement< - Promise - > { + public get noRangeIcon() { return $('[data-testid="icon-NoRange"]') } - public get LowRangeIcon(): ChainablePromiseElement< - Promise - > { + public get LowRangeIcon() { return $('[data-testid="icon-LowRange"]') } - public get MediumRangeIcon(): ChainablePromiseElement< - Promise - > { + public get MediumRangeIcon() { return $('[data-testid="icon-MediumRange"]') } - public get HighRangeIcon(): ChainablePromiseElement< - Promise - > { + public get HighRangeIcon() { return $('[data-testid="icon-HighRange"]') } - public get VeryHighRangeIcon(): ChainablePromiseElement< - Promise - > { + public get VeryHighRangeIcon() { return $('[data-testid="icon-VeryHighRange"]') } - public get disconnectButton(): ChainablePromiseElement< - Promise - > { + public get disconnectButton() { return $('[data-testid="disconnect-button"]') } - public get networkName(): ChainablePromiseElement< - Promise - > { + public get networkName() { return $('[data-testid="network-name"]') } - public get pureGrayImage(): ChainablePromiseElement< - Promise - > { + public get pureGrayImage() { return $('[data-testid="pure-gray"]') } - public get pureBlackImage(): ChainablePromiseElement< - Promise - > { + public get pureBlackImage() { return $('[data-testid="pure-black"]') } - public get aboutYourPureSerialNumber(): ChainablePromiseElement< - Promise - > { + public get aboutYourPureSerialNumber() { return $('[data-testid="serial-number-value"]') } - public get overviewSerialNumber(): ChainablePromiseElement< - Promise - > { + public get overviewSerialNumber() { return $('[data-testid="device-serial-number"]') } - public get muditaOSVersion(): ChainablePromiseElement< - Promise - > { + public get muditaOSVersion() { return $('[data-testid="os-version"]') } + + public get selectConnectedDevices() { + return $('[data-testid="icon-DotsInBox"]') + } } export default new OverviewPage() diff --git a/apps/mudita-center-e2e/src/page-objects/select-device.page.ts b/apps/mudita-center-e2e/src/page-objects/select-device.page.ts new file mode 100644 index 0000000000..6c6341126b --- /dev/null +++ b/apps/mudita-center-e2e/src/page-objects/select-device.page.ts @@ -0,0 +1,29 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { index } from "@orama/orama/dist/components" +import Page from "./page" + +class SelectDevicePage extends Page { + public get devicesList() { + return $("[data-testid='devices-list']") + } + public get availableDevices() { + return $$('[data-testid="available-device"]') + } + public get selectDeviceSerialNumber() { + return $$('[data-testid="available-device-serial-number"]') + } + public get selectDeviceName() { + return $$('[data-testid="available-device-name"]') + } + public get selectADeviceToContinueTitle() { + return $("h1*=Select a device to continue") + } + public getDeviceOnSelectModal(index: number) { + return $(`(//p[@data-testid="available-device-serial-number"])[${index}]`) + } +} +export default new SelectDevicePage() diff --git a/apps/mudita-center-e2e/src/page-objects/tabs.page.ts b/apps/mudita-center-e2e/src/page-objects/tabs.page.ts index 18481f4abd..795cb7a1d1 100644 --- a/apps/mudita-center-e2e/src/page-objects/tabs.page.ts +++ b/apps/mudita-center-e2e/src/page-objects/tabs.page.ts @@ -7,15 +7,11 @@ import { ChainablePromiseElement } from "webdriverio" import Page from "./page" class NavigationTabs extends Page { - public get muditaNewsTab(): ChainablePromiseElement< - Promise - > { + public get muditaNewsTab() { return $('[data-testid="icon-MenuNews"]') } - public get overviewTab(): ChainablePromiseElement< - Promise - > { + public get overviewTab() { return $('[data-testid="overview-link"]') } @@ -23,9 +19,11 @@ class NavigationTabs extends Page { await this.overviewTab.click() } - public get messagesTab(): ChainablePromiseElement< - Promise - > { + public get overviewKompaktTab() { + return $('[data-testid="icon-MenuOverview"]') + } + + public get messagesTab() { return $('[data-testid="overview-menu-link"]') } @@ -34,9 +32,7 @@ class NavigationTabs extends Page { await this.messagesTab.click() } - public get contactsTab(): ChainablePromiseElement< - Promise - > { + public get contactsTab() { return $('[data-testid="contacts-menu-link"]') } @@ -45,9 +41,7 @@ class NavigationTabs extends Page { await this.contactsTab.click() } - public get settingsTab(): ChainablePromiseElement< - Promise - > { + public get settingsTab() { return $('[data-testid="icon-MenuSettings"]') } @@ -55,7 +49,7 @@ class NavigationTabs extends Page { await this.settingsTab.click() } - public get helpTab(): ChainablePromiseElement> { + public get helpTab() { return $('[data-testid="help-menu-button"]') } diff --git a/apps/mudita-center-e2e/src/specs/news/news-check-offline.e2e.ts b/apps/mudita-center-e2e/src/specs/news/news-check-offline.e2e.ts index 30986448a1..5392cb08cc 100644 --- a/apps/mudita-center-e2e/src/specs/news/news-check-offline.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/news/news-check-offline.e2e.ts @@ -7,9 +7,16 @@ import { newsImageRegex, } from "../../consts/regex-const" import testsHelper from "../../helpers/tests.helper" +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" describe("News Page Check in Offline Mode", () => { before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + // Clear browser cache await browser.deleteAllCookies() await browser.execute("window.localStorage.clear();") @@ -114,6 +121,9 @@ describe("News Page Check in Offline Mode", () => { }) after(async () => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + // Switch back to online mode after finishing the tests await browser.setNetworkConditions({ offline: false, diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-match.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-match.e2e.ts new file mode 100644 index 0000000000..5311981766 --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-match.e2e.ts @@ -0,0 +1,75 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + apiConfigWithContacts, + contactsConfig, + contactsData, + menuWithContacts, +} from "../../../../../libs/e2e-mock/responses/src" + +describe("E2E mock match sample", () => { + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it.only("Connect device with two different responses for one endpoint", async () => { + // if body of FEATURE_CONFIGURATION request is equal to { feature: "contacts", lang: "en-US" } then return body: contactsConfig. + // in other cases return response without match filed + E2EMockClient.mockResponse({ + path: "path-1", + body: contactsConfig, + endpoint: "FEATURE_CONFIGURATION", + method: "GET", + status: 200, + match: { + expected: { feature: "contacts", lang: "en-US" }, + }, + }) + // if body of FEATURE_DATA request is equal to { feature: "contacts", lang: "en-US" } then return body: contactsConfig. + // in other cases return response without match filed + E2EMockClient.mockResponse({ + path: "path-1", + body: contactsData, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + match: { + expected: { feature: "contacts", lang: "en-US" }, + }, + }) + E2EMockClient.mockResponse({ + path: "path-1", + body: apiConfigWithContacts, + endpoint: "API_CONFIGURATION", + method: "GET", + status: 200, + }) + E2EMockClient.mockResponse({ + path: "path-1", + body: menuWithContacts, + endpoint: "MENU_CONFIGURATION", + method: "GET", + status: 200, + }) + + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: "first-serial-number", + }) + await browser.pause(6000) + const menuItem = await $(`//a[@href="#/generic/contacts"]`) + + await menuItem.waitForDisplayed({ timeout: 10000 }) + await expect(menuItem).toBeDisplayed() + + await browser.pause(10000) + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-available.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-available.e2e.ts new file mode 100644 index 0000000000..f43688c3be --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-available.e2e.ts @@ -0,0 +1,149 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import modalAppUpdatePage from "../../page-objects/modal-app-update.page" +import ModalPage from "../../page-objects/modal.page" +import packageInfo from "../../../../mudita-center/package.json" + +describe("Force Update MC - Successful Download", () => { + const newestAvailableVersion = "9.9.9" + + before(async function () { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + + E2EMockClient.setMockUpdateState({ + available: true, + version: newestAvailableVersion, + }) + + E2EMockClient.mockHttpResponse({ + url: "v2-app-configuration", + method: "GET", + status: 200, + data: { + centerVersion: "999.0.0", + productVersions: { + MuditaHarmony: "1.0.0", + MuditaPure: "1.0.0", + APIDevice: "1.0.0", + }, + }, + }) + }) + + it("Check update modal sections ", async () => { + console.log("PACKAGE INFO VERSION:" + packageInfo.version) + + // Header + const modalHeader = await modalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + // Available version + const paragraphAvailableVersion = + await modalAppUpdatePage.paragraphAvailableVersion + await expect(paragraphAvailableVersion).toBeDisplayed() + await expect(paragraphAvailableVersion).toHaveTextContaining( + "Update Mudita Center to" + ) + const textParagraphAvailableVersion = + await paragraphAvailableVersion.getText() + const availableAppVersion = textParagraphAvailableVersion.split("to ").pop() + console.log("AVAILABLE VERSION:" + availableAppVersion) + await expect(availableAppVersion).toBe(newestAvailableVersion) + + // Current version + const paragraphCurrentVersion = + await modalAppUpdatePage.paragraphCurrentVersion + await expect(paragraphCurrentVersion).toBeDisplayed() + await expect(paragraphCurrentVersion).toHaveTextContaining( + "Update it to use the full version of the Mudita Center. Your current version:" + ) + const textParagraphCurrentVersion = await paragraphCurrentVersion.getText() + const currentAppVersion = textParagraphCurrentVersion.split(": ").pop() + console.log("CURRENT VERSION:" + currentAppVersion) + + // Privacy policy + const paragraphPrivacyPolicy = + await modalAppUpdatePage.paragraphPrivacyPolicy + await expect(paragraphPrivacyPolicy).toBeDisplayed() + await expect(paragraphPrivacyPolicy).toHaveText( + "Please accept the Privacy Policy to start updating Mudita Center." + ) + + const linkPrivacyPolicy = await modalAppUpdatePage.linkPrivacyPolicy + await expect(linkPrivacyPolicy).toBeDisplayed() + await expect(linkPrivacyPolicy).toHaveText("Privacy Policy") + + const linkColor = await linkPrivacyPolicy.getCSSProperty("color") + await expect(linkColor.value).toBe("rgba(109,155,188,1)") + const linkDecoration = await linkPrivacyPolicy.getCSSProperty( + "text-decoration" + ) + await expect(linkDecoration.value).toBe( + "underline solid rgb(109, 155, 188)" + ) + + const checkboxPrivacyPolicy = await modalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + await expect(checkboxPrivacyPolicy).not.toBeChecked() + + // Button: UPDATE + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate.isDisplayed()) + await expect(buttonUpdate).not.toBeClickable() + + // Close modal button + const modalCloseButton = await ModalPage.modalCloseButton + await expect(modalCloseButton).not.toBeDisplayed() + }) + + it("Button UPDATE is clickable after selecting the checkbox", async () => { + const checkboxPrivacyPolicy = await modalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await expect(buttonUpdate).not.toBeClickable() + + await checkboxPrivacyPolicy.click() + await expect(checkboxPrivacyPolicy).toBeChecked() + + await expect(buttonUpdate).toBeClickable() + }) + + it("Check Updating Mudita Center modal", async () => { + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await buttonUpdate.click() + + const modalHeader = await modalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const paragraphUpdatingMuditaCenter = + await modalAppUpdatePage.paragraphUpdatingMuditaCenter + await expect(paragraphUpdatingMuditaCenter).toBeDisplayed() + await expect(paragraphUpdatingMuditaCenter).toHaveText( + "Updating Mudita Center" + ) + + const spinnerLoader = await modalAppUpdatePage.spinnerLoader + await expect(spinnerLoader).toBeDisplayed() + const spinnerColor = await spinnerLoader.getCSSProperty("color") + await expect(spinnerColor.value).toBe("rgba(109,155,188,1)") + + const spinnerAnimation = await spinnerLoader.getCSSProperty("animation") + await expect(spinnerAnimation.value).toBe( + "chase 2.5s linear 0s infinite normal both running" + ) + + const paragraphPleaseWait = await modalAppUpdatePage.paragraphPleaseWait + await expect(paragraphPleaseWait).toBeDisplayed() + await expect(paragraphPleaseWait).toHaveText( + "Please wait while Mudita Center is being updated." + ) + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-error.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-error.e2e.ts new file mode 100644 index 0000000000..516db66ab5 --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-force-update-error.e2e.ts @@ -0,0 +1,149 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import ModalPage from "../../page-objects/modal.page" +import modalAppUpdatePage from "../../page-objects/modal-app-update.page" +import modalAppUpdateErrorPage from "../../page-objects/modal-app-update-error.page" +import packageInfo from "../../../../mudita-center/package.json" + +describe("Force Update MC - Unsuccessful Download", () => { + const newestAvailableVersion = "9.9.9" + + before(async function () { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + + E2EMockClient.setMockUpdateState({ + available: true, + downloaded: false, + version: newestAvailableVersion, + }) + + E2EMockClient.mockHttpResponse({ + url: "v2-app-configuration", + method: "GET", + status: 200, + data: { + centerVersion: "999.0.0", + productVersions: { + MuditaHarmony: "1.0.0", + MuditaPure: "1.0.0", + APIDevice: "1.0.0", + }, + }, + }) + }) + + it("Check update modal sections ", async () => { + console.log("PACKAGE INFO VERSION:" + packageInfo.version) + + // Header + const modalHeader = await modalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + // Available version + const paragraphAvailableVersion = + await modalAppUpdatePage.paragraphAvailableVersion + await expect(paragraphAvailableVersion).toBeDisplayed() + await expect(paragraphAvailableVersion).toHaveTextContaining( + "Update Mudita Center to" + ) + const textParagraphAvailableVersion = + await paragraphAvailableVersion.getText() + const availableAppVersion = textParagraphAvailableVersion.split("to ").pop() + console.log("AVAILABLE VERSION:" + availableAppVersion) + await expect(availableAppVersion).toBe(newestAvailableVersion) + + // Current version + const paragraphCurrentVersion = + await modalAppUpdatePage.paragraphCurrentVersion + await expect(paragraphCurrentVersion).toBeDisplayed() + await expect(paragraphCurrentVersion).toHaveTextContaining( + "Update it to use the full version of the Mudita Center. Your current version:" + ) + const textParagraphCurrentVersion = await paragraphCurrentVersion.getText() + const currentAppVersion = textParagraphCurrentVersion.split(": ").pop() + console.log("CURRENT VERSION:" + currentAppVersion) + + // Privacy policy + const paragraphPrivacyPolicy = + await modalAppUpdatePage.paragraphPrivacyPolicy + await expect(paragraphPrivacyPolicy).toBeDisplayed() + await expect(paragraphPrivacyPolicy).toHaveText( + "Please accept the Privacy Policy to start updating Mudita Center." + ) + + const linkPrivacyPolicy = await modalAppUpdatePage.linkPrivacyPolicy + await expect(linkPrivacyPolicy).toBeDisplayed() + await expect(linkPrivacyPolicy).toHaveText("Privacy Policy") + + const linkColor = await linkPrivacyPolicy.getCSSProperty("color") + await expect(linkColor.value).toBe("rgba(109,155,188,1)") + const linkDecoration = await linkPrivacyPolicy.getCSSProperty( + "text-decoration" + ) + await expect(linkDecoration.value).toBe( + "underline solid rgb(109, 155, 188)" + ) + + const checkboxPrivacyPolicy = await modalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + await expect(checkboxPrivacyPolicy).not.toBeChecked() + + // Button: UPDATE + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate.isDisplayed()) + await expect(buttonUpdate).not.toBeClickable() + + // Close modal button + const modalCloseButton = await ModalPage.modalCloseButton + await expect(modalCloseButton).not.toBeDisplayed() + }) + + it("Button UPDATE is clickable after selecting the checkbox", async () => { + const checkboxPrivacyPolicy = await modalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await expect(buttonUpdate).not.toBeClickable() + + await checkboxPrivacyPolicy.click() + await expect(checkboxPrivacyPolicy).toBeChecked() + + await expect(buttonUpdate).toBeClickable() + }) + + it("Check Error modal", async () => { + const buttonUpdate = await modalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await buttonUpdate.click() + + const modalHeader = await modalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const infoIcon = await modalAppUpdateErrorPage.infoIcon + await expect(infoIcon).toBeDisplayed() + const infoIconSize = await infoIcon.getSize() + await expect(infoIconSize.width).toBe(48) + await expect(infoIconSize.height).toBe(48) + + const errorLabel = await modalAppUpdateErrorPage.errorLabel + await expect(errorLabel).toBeDisplayed() + await expect(errorLabel).toHaveText("Error") + + const paragraphPleaseRestart = + await modalAppUpdateErrorPage.pleaseRestartParagraph + await expect(paragraphPleaseRestart).toBeDisplayed() + await expect(paragraphPleaseRestart).toHaveText( + "Please restart the app or update it manually." + ) + + const buttonClose = await modalAppUpdateErrorPage.closeButton + await expect(buttonClose).toBeDisplayed() + await expect(buttonClose).toHaveText("CLOSE") + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-available.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-available.e2e.ts new file mode 100644 index 0000000000..b09e01abdb --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-available.e2e.ts @@ -0,0 +1,197 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import ModalAppUpdatePage from "../../page-objects/modal-app-update.page" +import ModalAppUpdateLaterPage from "../../page-objects/modal-app-update-later.page" +import ModalPage from "../../page-objects/modal.page" +import packageInfo from "../../../../mudita-center/package.json" +import { sleep } from "../../helpers/sleep.helper" +import HomePage from "../../page-objects/home.page" +import SettingsPage from "../../page-objects/settings.page" +import NavigationTabs from "../../page-objects/tabs.page" + +describe("Soft Update MC - Successful Download", () => { + const newestAvailableVersion = "9.9.9" + + before(async function () { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + + E2EMockClient.setMockUpdateState({ + available: true, + version: newestAvailableVersion, + }) + + E2EMockClient.mockHttpResponse({ + url: "v2-app-configuration", + method: "GET", + status: 200, + data: { + centerVersion: "0.0.1", + productVersions: { + MuditaHarmony: "1.0.0", + MuditaPure: "1.0.0", + APIDevice: "1.0.0", + }, + }, + }) + }) + + it("Check update modal sections ", async () => { + console.log("PACKAGE INFO VERSION:" + packageInfo.version) + + const modalHeader = await ModalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const paragraphAvailableVersion = + await ModalAppUpdatePage.paragraphAvailableVersion + await expect(paragraphAvailableVersion).toBeDisplayed() + await expect(paragraphAvailableVersion).toHaveTextContaining( + "Update Mudita Center to" + ) + const textParagraphAvailableVersion = + await paragraphAvailableVersion.getText() + const availableAppVersion = textParagraphAvailableVersion.split("to ").pop() + console.log("AVAILABLE VERSION:" + availableAppVersion) + await expect(availableAppVersion).toBe(newestAvailableVersion) + + const paragraphCurrentVersion = + await ModalAppUpdatePage.paragraphCurrentVersion + await expect(paragraphCurrentVersion).toBeDisplayed() + await expect(paragraphCurrentVersion).toHaveTextContaining( + "Update it to use the full version of the Mudita Center. Your current version:" + ) + const textParagraphCurrentVersion = await paragraphCurrentVersion.getText() + const currentAppVersion = textParagraphCurrentVersion.split(": ").pop() + console.log("CURRENT VERSION:" + currentAppVersion) + + // Privacy policy + const paragraphPrivacyPolicy = + await ModalAppUpdatePage.paragraphPrivacyPolicy + await expect(paragraphPrivacyPolicy).toBeDisplayed() + await expect(paragraphPrivacyPolicy).toHaveText( + "Please accept the Privacy Policy to start updating Mudita Center." + ) + + const linkPrivacyPolicy = await ModalAppUpdatePage.linkPrivacyPolicy + await expect(linkPrivacyPolicy).toBeDisplayed() + await expect(linkPrivacyPolicy).toHaveText("Privacy Policy") + + const linkColor = await linkPrivacyPolicy.getCSSProperty("color") + await expect(linkColor.value).toBe("rgba(109,155,188,1)") + const linkDecoration = await linkPrivacyPolicy.getCSSProperty( + "text-decoration" + ) + await expect(linkDecoration.value).toBe( + "underline solid rgb(109, 155, 188)" + ) + + const checkboxPrivacyPolicy = await ModalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + await expect(checkboxPrivacyPolicy).not.toBeChecked() + + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate.isDisplayed()) + await expect(buttonUpdate).not.toBeClickable() + + const modalCloseButton = await ModalPage.modalCloseButton + await expect(modalCloseButton).toBeDisplayed() + await modalCloseButton.click() + }) + it("Check update later modal", async () => { + const modalHeader = await ModalAppUpdateLaterPage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + const paragraphAvailableVersion = + await ModalAppUpdateLaterPage.paragraphAvailableVersion + await expect(paragraphAvailableVersion).toBeDisplayed() + await expect(paragraphAvailableVersion).toHaveTextContaining( + "Update Mudita Center to" + ) + const paragraphUpdateLaterPrivacyPolicy = + await ModalAppUpdateLaterPage.paragraphUpdateLaterPrivacyPolicy + await expect(paragraphUpdateLaterPrivacyPolicy).toBeDisplayed() + await expect(paragraphUpdateLaterPrivacyPolicy).toHaveTextContaining( + "To be able to fully use the application, please agree to the Privacy Policy and update Mudita Center." + ) + + const buttonUpdateLater = await ModalAppUpdateLaterPage.buttonUpdateLater + await expect(buttonUpdateLater).toBeDisplayed() + await expect(buttonUpdateLater).toHaveText("UPDATE LATER") + await expect(buttonUpdateLater).toBeClickable() + + const modalCloseButton = await ModalAppUpdateLaterPage.modalCloseButton + await expect(modalCloseButton).toBeDisplayed() + await modalCloseButton.click() + + const homeHeader = await HomePage.homeHeader + await expect(homeHeader).toBeDisplayed() + await expect(homeHeader).toHaveText("Welcome to Mudita Center") + const notNowButton = await HomePage.notNowButton + await expect(notNowButton).toBeDisplayed() + await notNowButton.click() + }) + it("Go back to Soft Update Modal.", async () => { + const settingsTab = await NavigationTabs.settingsTab + await settingsTab.waitForDisplayed() + await settingsTab.click() + + const aboutTab = await SettingsPage.aboutTab + await aboutTab.waitForDisplayed() + await aboutTab.click() + + const aboutCheckForUpdatesButton = + await SettingsPage.aboutCheckForUpdatesButton + await aboutCheckForUpdatesButton.waitForDisplayed() + await aboutCheckForUpdatesButton.click() + }) + + it("Button UPDATE is clickable after selecting the checkbox", async () => { + const checkboxPrivacyPolicy = await ModalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await expect(buttonUpdate).not.toBeClickable() + + await checkboxPrivacyPolicy.click() + await expect(checkboxPrivacyPolicy).toBeChecked() + + await expect(buttonUpdate).toBeClickable() + }) + + it("Soft Update the app", async () => { + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await buttonUpdate.click() + + const modalHeader = await ModalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const paragraphUpdatingMuditaCenter = + await ModalAppUpdatePage.paragraphUpdatingMuditaCenter + await expect(paragraphUpdatingMuditaCenter).toBeDisplayed() + await expect(paragraphUpdatingMuditaCenter).toHaveText( + "Updating Mudita Center" + ) + + const spinnerLoader = await ModalAppUpdatePage.spinnerLoader + await expect(spinnerLoader).toBeDisplayed() + const spinnerColor = await spinnerLoader.getCSSProperty("color") + await expect(spinnerColor.value).toBe("rgba(109,155,188,1)") + + const spinnerAnimation = await spinnerLoader.getCSSProperty("animation") + await expect(spinnerAnimation.value).toBe( + "chase 2.5s linear 0s infinite normal both running" + ) + + const paragraphPleaseWait = await ModalAppUpdatePage.paragraphPleaseWait + await expect(paragraphPleaseWait).toBeDisplayed() + await expect(paragraphPleaseWait).toHaveText( + "Please wait while Mudita Center is being updated." + ) + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-error.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-error.e2e.ts new file mode 100644 index 0000000000..b3d5103c8b --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-mc-soft-update-error.e2e.ts @@ -0,0 +1,144 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import ModalAppUpdatePage from "../../page-objects/modal-app-update.page" +import modalAppUpdateErrorPage from "../../page-objects/modal-app-update-error.page" +import ModalPage from "../../page-objects/modal.page" +import packageInfo from "../../../../mudita-center/package.json" + +describe("Soft Update MC - Unsuccessful Download", () => { + const newestAvailableVersion = "9.9.9" + + before(async function () { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + + E2EMockClient.setMockUpdateState({ + available: true, + downloaded: false, + version: newestAvailableVersion, + }) + + E2EMockClient.mockHttpResponse({ + url: "v2-app-configuration", + method: "GET", + status: 200, + data: { + centerVersion: "0.0.1", + productVersions: { + MuditaHarmony: "1.0.0", + MuditaPure: "1.0.0", + APIDevice: "1.0.0", + }, + }, + }) + }) + + it("Check update modal sections ", async () => { + console.log("PACKAGE INFO VERSION:" + packageInfo.version) + + const modalHeader = await ModalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const paragraphAvailableVersion = + await ModalAppUpdatePage.paragraphAvailableVersion + await expect(paragraphAvailableVersion).toBeDisplayed() + await expect(paragraphAvailableVersion).toHaveTextContaining( + "Update Mudita Center to" + ) + const textParagraphAvailableVersion = + await paragraphAvailableVersion.getText() + const availableAppVersion = textParagraphAvailableVersion.split("to ").pop() + console.log("AVAILABLE VERSION:" + availableAppVersion) + await expect(availableAppVersion).toBe(newestAvailableVersion) + + const paragraphCurrentVersion = + await ModalAppUpdatePage.paragraphCurrentVersion + await expect(paragraphCurrentVersion).toBeDisplayed() + await expect(paragraphCurrentVersion).toHaveTextContaining( + "Update it to use the full version of the Mudita Center. Your current version:" + ) + const textParagraphCurrentVersion = await paragraphCurrentVersion.getText() + const currentAppVersion = textParagraphCurrentVersion.split(": ").pop() + console.log("CURRENT VERSION:" + currentAppVersion) + + // Privacy policy + const paragraphPrivacyPolicy = + await ModalAppUpdatePage.paragraphPrivacyPolicy + await expect(paragraphPrivacyPolicy).toBeDisplayed() + await expect(paragraphPrivacyPolicy).toHaveText( + "Please accept the Privacy Policy to start updating Mudita Center." + ) + + const linkPrivacyPolicy = await ModalAppUpdatePage.linkPrivacyPolicy + await expect(linkPrivacyPolicy).toBeDisplayed() + await expect(linkPrivacyPolicy).toHaveText("Privacy Policy") + + const linkColor = await linkPrivacyPolicy.getCSSProperty("color") + await expect(linkColor.value).toBe("rgba(109,155,188,1)") + const linkDecoration = await linkPrivacyPolicy.getCSSProperty( + "text-decoration" + ) + await expect(linkDecoration.value).toBe( + "underline solid rgb(109, 155, 188)" + ) + + const checkboxPrivacyPolicy = await ModalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + await expect(checkboxPrivacyPolicy).not.toBeChecked() + + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate.isDisplayed()) + await expect(buttonUpdate).not.toBeClickable() + + const modalCloseButton = await ModalPage.modalCloseButton + await expect(modalCloseButton).toBeDisplayed() + }) + + it("Button UPDATE is clickable after selecting the checkbox", async () => { + const checkboxPrivacyPolicy = await ModalAppUpdatePage.checkboxPrivacyPolicy + await expect(checkboxPrivacyPolicy).toBeDisplayed() + + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await expect(buttonUpdate).not.toBeClickable() + + await checkboxPrivacyPolicy.click() + await expect(checkboxPrivacyPolicy).toBeChecked() + + await expect(buttonUpdate).toBeClickable() + }) + + it("Check Error modal", async () => { + const buttonUpdate = await ModalAppUpdatePage.buttonUpdate + await expect(buttonUpdate).toBeDisplayed() + await buttonUpdate.click() + + const modalHeader = await ModalAppUpdatePage.modalHeader + await expect(modalHeader).toBeDisplayed() + await expect(modalHeader).toHaveText("Mudita Center") + + const infoIcon = await modalAppUpdateErrorPage.infoIcon + await expect(infoIcon).toBeDisplayed() + const infoIconSize = await infoIcon.getSize() + await expect(infoIconSize.width).toBe(48) + await expect(infoIconSize.height).toBe(48) + + const errorLabel = await modalAppUpdateErrorPage.errorLabel + await expect(errorLabel).toBeDisplayed() + await expect(errorLabel).toHaveText("Error") + + const paragraphPleaseRestart = + await modalAppUpdateErrorPage.pleaseRestartParagraph + await expect(paragraphPleaseRestart).toBeDisplayed() + await expect(paragraphPleaseRestart).toHaveText( + "Please restart the app or update it manually." + ) + + const buttonClose = await modalAppUpdateErrorPage.closeButton + await expect(buttonClose).toBeDisplayed() + await expect(buttonClose).toHaveText("CLOSE") + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-sample.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-sample.e2e.ts index e069538b85..228385d794 100644 --- a/apps/mudita-center-e2e/src/specs/overview/e2e-mock-sample.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-mock-sample.e2e.ts @@ -74,6 +74,54 @@ describe("E2E mock sample - overview view", () => { await expect(drawerHeader).toBeDisplayed() }) + it("Add third device", async () => { + E2EMockClient.addDevice({ + path: "path-3", + serialNumber: "third-serial-number", + }) + await browser.pause(6000) + + const drawerHeader = $(`//*[text()='Select a device']`) + await drawerHeader.waitForDisplayed() + await expect(drawerHeader).toBeDisplayed() + }) + + it("Add fourth device", async () => { + E2EMockClient.addDevice({ + path: "path-4", + serialNumber: "fourth-serial-number", + }) + await browser.pause(6000) + + const drawerHeader = $(`//*[text()='Select a device']`) + await drawerHeader.waitForDisplayed() + await expect(drawerHeader).toBeDisplayed() + }) + + it("Add fifth device", async () => { + E2EMockClient.addDevice({ + path: "path-5", + serialNumber: "fifth-serial-number", + }) + await browser.pause(6000) + + const drawerHeader = $(`//*[text()='Select a device']`) + await drawerHeader.waitForDisplayed() + await expect(drawerHeader).toBeDisplayed() + }) + + it("Add sixth device", async () => { + E2EMockClient.addDevice({ + path: "path-6", + serialNumber: "sixth-serial-number", + }) + await browser.pause(6000) + + const drawerHeader = $(`//*[text()='Select a device']`) + await drawerHeader.waitForDisplayed() + await expect(drawerHeader).toBeDisplayed() + }) + it("Remove first device", async () => { E2EMockClient.removeDevice("path-1") await browser.pause(6000) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-overview.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-overview.e2e.ts new file mode 100644 index 0000000000..4d2ccbc4c4 --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-overview.e2e.ts @@ -0,0 +1,86 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + outboxReloadOverview, + overviewDataWithOneSimCard +} from "../../../../../libs/e2e-mock/responses/src" +import screenshotHelper from "../../helpers/screenshot.helper" + +describe("E2E reset mock sample - overview view", () => { + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect device", async () => { + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: "first-serial-number", + }) + + await browser.pause(6000) + const menuItem = await $(`//a[@href="#/generic/mc-overview"]`) + + await menuItem.waitForDisplayed({ timeout: 10000 }) + await expect(menuItem).toBeDisplayed() + }) + + it("Overwrite device response", async () => { + + // overwrite default response for given device + E2EMockClient.mockResponse({ + path: "path-1", + body: overviewDataWithOneSimCard, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + // overwrite newest response for given device + E2EMockClient.mockResponseOnce({ + path: "path-1", + body: outboxReloadOverview, + endpoint: "OUTBOX", + method: "GET", + status: 200, + }) + + + await browser.pause(30000) + }) + + it("Reset mock", async () => { + E2EMockClient.mockReset({ + path: "path-1", + requests: [ + { endpoint: "FEATURE_DATA", method: "GET" }, + { + endpoint: "FEATURE_CONFIGURATION", + method: "GET", + }, + { + endpoint: "MENU_CONFIGURATION", + method: "GET", + }, + { + endpoint: "OUTBOX", + method: "GET", + }, + ], + }) + + + await browser.pause(30000) + }) + + it("Remove first device", async () => { + E2EMockClient.removeDevice("path-1") + await browser.pause(6000) + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-sample.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-sample.e2e.ts new file mode 100644 index 0000000000..34268246af --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/e2e-reset-mock-sample.e2e.ts @@ -0,0 +1,88 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + outboxReloadOverview, + overviewDataWithoutBadge, +} from "../../../../../libs/e2e-mock/responses/src" +import screenshotHelper from "../../helpers/screenshot.helper" + +describe("E2E reset mock sample", () => { + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect locked device", async () => { + E2EMockClient.mockResponse({ + path: "path-1", + body: {}, + endpoint: "FEATURE_DATA", + method: "GET", + status: 423, + }) + E2EMockClient.mockResponse({ + path: "path-1", + body: {}, + endpoint: "FEATURE_CONFIGURATION", + method: "GET", + status: 423, + }) + E2EMockClient.mockResponse({ + path: "path-1", + body: {}, + endpoint: "MENU_CONFIGURATION", + method: "GET", + status: 423, + }) + + E2EMockClient.mockResponse({ + path: "path-1", + body: {}, + endpoint: "OUTBOX", + method: "GET", + status: 423, + }) + + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: "first-serial-number", + }) + + await browser.pause(10000) + const lockScreen = await $(`//*[text()="Unlock your phone"]`) + + await lockScreen.waitForDisplayed({ timeout: 10000 }) + await expect(lockScreen).toBeDisplayed() + await browser.pause(2000) + }) + + it("Unlock device", async () => { + E2EMockClient.mockReset({ + path: "path-1", + requests: [ + { endpoint: "FEATURE_DATA", method: "GET" }, + { + endpoint: "FEATURE_CONFIGURATION", + method: "GET", + }, + { + endpoint: "MENU_CONFIGURATION", + method: "GET", + }, + { + endpoint: "OUTBOX", + method: "GET", + }, + ], + }) + + await browser.pause(10000) + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/home-page-device-not-connecting.e2e.ts b/apps/mudita-center-e2e/src/specs/overview/home-page-device-not-connecting.e2e.ts index e4ae33070e..a02f2785d1 100644 --- a/apps/mudita-center-e2e/src/specs/overview/home-page-device-not-connecting.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/overview/home-page-device-not-connecting.e2e.ts @@ -46,7 +46,6 @@ describe("Home Screen Page", () => { await tryAgainParagraph.click() }) it("Click Contact Support & Verify Contents", async () => { - screenshotHelper.makeViewScreenshot() const contactSupportButton = await HomePage.contactSupportButton const muditaCenterSupportModalHeader = await HomePage.muditaCenterSupportModalHeader diff --git a/apps/mudita-center-e2e/src/specs/overview/kompakt-about.ts b/apps/mudita-center-e2e/src/specs/overview/kompakt-about.ts new file mode 100644 index 0000000000..dce12565fe --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/kompakt-about.ts @@ -0,0 +1,128 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { overviewDataWithOneSimCard } from "../../../../../libs/e2e-mock/responses/src" +import homePage from "../../page-objects/home.page" +import menu from "../../page-objects/menu.page" +import overviewKompaktPage from "../../page-objects/overview-kompakt.page" +import aboutKompaktPage from "../../page-objects/about-kompakt.page" +import modalSarPage from "../../page-objects/modal-sar.page" +import { kompaktImeiRegex } from "../../consts/regex-const" + +describe("Checking About your Kompakt", () => { + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + it("Connect device", async () => { + E2EMockClient.mockResponse({ + path: "path-1", + body: overviewDataWithOneSimCard, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: "first-serial-number", + }) + + await browser.pause(6000) + const menuOverviewLink = await menu.overviewLink + await menuOverviewLink.waitForDisplayed({ timeout: 10000 }) + await expect(menuOverviewLink).toBeDisplayed() + }) + + it("Check SN", async () => { + const serialNumberValue = await overviewKompaktPage.serialNumberValue + await expect(serialNumberValue).toHaveText( + overviewDataWithOneSimCard.summary.about.serialNumber.text + ) + }) + + it("Go to ABOUT YOUR DEVICE", async () => { + const aboutYourDevice = await overviewKompaktPage.aboutYourDevice + await aboutYourDevice.waitForClickable() + await aboutYourDevice.click() + + // Header + const aboutHeader = await aboutKompaktPage.aboutHeader + await expect(aboutHeader).toBeDisplayed() + await expect(aboutHeader).toHaveText("About your device") + }) + + it("Verify About Your Device page", async () => { + // Subtitle + const aboutSubtitle = await aboutKompaktPage.aboutSubtitle + await expect(aboutSubtitle).toHaveText("Device details") + // SN + const serialNumberLabel = await aboutKompaktPage.serialNumberLabel + await expect(serialNumberLabel).toHaveText("Serial number") + const serialNumberValue = await aboutKompaktPage.serialNumberValue + await expect(serialNumberValue).toHaveText( + overviewDataWithOneSimCard.summary.about.serialNumber.text + ) + // IMEI 1 + const imei1Label = await aboutKompaktPage.imei1Label + await expect(imei1Label).toHaveText("IMEI (sim slot 1)") + const imei1Value = await aboutKompaktPage.imei1Value + const imei1 = await imei1Value.getText() + await expect(imei1Value).toHaveText(kompaktImeiRegex) + // IMEI 2 + const imei2Label = await aboutKompaktPage.imei2Label + await expect(imei2Label).toHaveText("IMEI (sim slot 2)") + const imei2Value = await aboutKompaktPage.imei2Value + const imei2 = await imei2Value.getText() + await expect(imei2Value).toHaveText(kompaktImeiRegex) + //SAR + const sarLabel = await aboutKompaktPage.sarLabel + await expect(sarLabel).toHaveText("SAR") + const sarButton = await aboutKompaktPage.sarButton + await expect(sarButton).toHaveText("Check SAR information") + await expect(sarButton).toBeClickable() + }) + + it("Go to SAR information", async () => { + const sarButton = await aboutKompaktPage.sarButton + await sarButton.waitForClickable() + await sarButton.click() + const sarHeader = await aboutKompaktPage.sarHeader + await expect(sarHeader).toHaveText("SAR") + // TBD: SAR content + scroll + }) + + it("Close SAR information", async () => { + const modalCloseButton = await modalSarPage.modalCloseButton + await expect(modalCloseButton).toBeDisplayed() + await modalCloseButton.click() + }) + + it("Go to Overview", async () => { + const backToOverviewIcon = await aboutKompaktPage.backToOverviewIcon + await backToOverviewIcon.isDisplayed() + + const backToOverviewLabel = await aboutKompaktPage.backToOverviewLabel + await backToOverviewLabel.isDisplayed() + backToOverviewLabel.click() + + const header = await overviewKompaktPage.header + await header.isDisplayed() + + const menuOverviewLink = await menu.overviewLink + await expect(menuOverviewLink).not.toBeClickable() + }) + + it("Disconnect the device and check if Welcome screen is present", async () => { + E2EMockClient.removeDevice("path-1") + const homeHeader = await homePage.homeHeader + await expect(homeHeader).toBeDisplayed() + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/kompakt-overview.ts b/apps/mudita-center-e2e/src/specs/overview/kompakt-overview.ts new file mode 100644 index 0000000000..f01325dcf7 --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/kompakt-overview.ts @@ -0,0 +1,134 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { overviewDataWithOneSimCard } from "../../../../../libs/e2e-mock/responses/src" +import OverviewPage from "../../page-objects/overview.page" +import OverviewKompaktPage from "../../page-objects/overview-kompakt.page" +import HomePage from "../../page-objects/home.page" +import tabsPage from "../../page-objects/tabs.page" +import { kompaktImageRegex } from "../../consts/regex-const" + +describe("E2E mock sample - overview view", () => { + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect device", async () => { + E2EMockClient.mockResponse({ + path: "path-1", + body: overviewDataWithOneSimCard, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: "first-serial-number", + }) + + await browser.pause(6000) + const menuItem = await $(`//a[@href="#/generic/mc-overview"]`) + + await menuItem.waitForDisplayed({ timeout: 10000 }) + await expect(menuItem).toBeDisplayed() + }) + + it("Verify Overview Page", async () => { + const kompaktImage = await OverviewKompaktPage.kompaktImage + await expect(kompaktImage).toBeDisplayed() + await expect(kompaktImage).toHaveAttribute("src", kompaktImageRegex) + + const kompaktOsVersion = await OverviewKompaktPage.kompaktOsVersion + await expect(kompaktOsVersion).toBeDisplayed() + await expect(kompaktOsVersion).toHaveText("Mudita OS") + + const kompaktOsVersionLabel = + await OverviewKompaktPage.kompaktOsVersionLabel + await expect(kompaktOsVersionLabel).toBeDisplayed() + await expect(kompaktOsVersionLabel).toHaveText("Current version:") + + const serialNumberLabel = await OverviewKompaktPage.serialNumberLabel + const serialNumberValue = await OverviewKompaktPage.serialNumberValue + await expect(serialNumberLabel).toHaveText("Serial number") + await expect(serialNumberValue).toHaveText( + overviewDataWithOneSimCard.summary.about.serialNumber.text.toString() + ) + + const aboutYourDevice = await OverviewKompaktPage.aboutYourDevice + await expect(aboutYourDevice).toBeDisplayed() + await expect(aboutYourDevice).toBeClickable + await aboutYourDevice.click() + + const sarInformationButtonKompakt = + await OverviewKompaktPage.sarInformationButtonKompakt + const sarInformationPopup = await OverviewKompaktPage.sarInformationPopup + await expect(sarInformationButtonKompakt).toBeDisplayed() + await sarInformationButtonKompakt.click() + await expect(sarInformationPopup).toBeDisplayed() + + const sarInformationPopupCloseButton = + await OverviewKompaktPage.sarInformationPopupCloseButton + await sarInformationPopupCloseButton.waitForClickable() + await sarInformationPopupCloseButton.click() + + const backArrowButton = OverviewKompaktPage.backArrowButton + await backArrowButton.waitForClickable() + await backArrowButton.click() + + const createBackupButton = await OverviewPage.createBackupButton + await expect(createBackupButton).toBeDisplayed() + await expect(createBackupButton).toBeClickable() + + const backupInfo = await OverviewKompaktPage.backupInfo + await expect(backupInfo).toBeDisplayed() + await expect(backupInfo).toHaveTextContaining( + "You haven’t backed up your device yet.\nCreate a backup file to protect against data loss." + ) + + const kompaktBatteryIcon = await OverviewKompaktPage.kompaktBatteryIcon + await expect(kompaktBatteryIcon).toBeDisplayed() + + const kompaktBatteryLevelValue = + await OverviewKompaktPage.kompaktBatteryLevelValue + await expect(kompaktBatteryLevelValue).toBeDisplayed() + await expect(kompaktBatteryLevelValue).toHaveText("100%") + + const kompaktNetworkName = await OverviewKompaktPage.kompaktNetworkName + await expect(kompaktNetworkName).toBeDisplayed() + await expect(kompaktNetworkName).toHaveText("T-Mobile") + + const kompaktSignalIcon = await OverviewKompaktPage.kompaktSignalIcon + await expect(kompaktSignalIcon).toBeDisplayed() + await expect(kompaktSignalIcon).toHaveAttributeContaining( + "data-testid", + "icon-network-signal-2" + ) + + const kompaktSimCard1Subtext = + await OverviewKompaktPage.kompaktSimCard1Subtext + await expect(kompaktSimCard1Subtext).toBeDisplayed() + await expect(kompaktSimCard1Subtext).toHaveText("SIM 1") + }) + + it("Click between Tabs and check them", async () => { + const muditaNewsTab = await tabsPage.muditaNewsTab + await muditaNewsTab.waitForClickable() + await muditaNewsTab.click() + + const overviewKompaktTab = await tabsPage.overviewKompaktTab + await overviewKompaktTab.waitForClickable() + await overviewKompaktTab.click() + }) + + it("Disconnect the device and check if Welcome screen is present", async () => { + E2EMockClient.removeDevice("path-1") + await HomePage.homeHeader.waitForDisplayed() + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/overview/kompakt-switching-devices.ts b/apps/mudita-center-e2e/src/specs/overview/kompakt-switching-devices.ts new file mode 100644 index 0000000000..ad35d88fe8 --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/overview/kompakt-switching-devices.ts @@ -0,0 +1,149 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + overviewDataWithOneSimCard, + overviewDataWithOneSimCard2nd, +} from "../../../../../libs/e2e-mock/responses/src" +import OverviewKompaktPage from "../../page-objects/overview-kompakt.page" +import HomePage from "../../page-objects/home.page" +import { kompaktImageRegex } from "../../consts/regex-const" +import overviewPage from "../../page-objects/overview.page" +import drawerPage from "../../page-objects/drawer.page" + +describe("Kompakt switching devices", () => { + const firstSerialNumber = "KOM1234567890" + const secondSerialNumber = "KOM1234567892" + + before(async () => { + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect device", async () => { + E2EMockClient.mockResponse({ + path: "path-1", + body: overviewDataWithOneSimCard, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: "path-1", + serialNumber: firstSerialNumber, + }) + + await browser.pause(6000) + const menuItem = await $(`//a[@href="#/generic/mc-overview"]`) + + await menuItem.waitForDisplayed({ timeout: 10000 }) + await expect(menuItem).toBeDisplayed() + }) + + it("Verify Overview Page", async () => { + const kompaktImage = await OverviewKompaktPage.kompaktImage + await expect(kompaktImage).toBeDisplayed() + await expect(kompaktImage).toHaveAttribute("src", kompaktImageRegex) + + const kompaktOsVersion = await OverviewKompaktPage.kompaktOsVersion + await expect(kompaktOsVersion).toBeDisplayed() + + const kompaktSimCard1Subtext = + await OverviewKompaktPage.kompaktSimCard1Subtext + await expect(kompaktSimCard1Subtext).toHaveText("SIM 1") + + const kompaktNetworkName = await OverviewKompaktPage.kompaktNetworkName + await expect(kompaktNetworkName).toBeDisplayed() + await expect(kompaktNetworkName).toHaveText("T-Mobile") + + const kompaktBatteryLevelValue = + await OverviewKompaktPage.kompaktBatteryLevelValue + await expect(kompaktBatteryLevelValue).toBeDisplayed() + await expect(kompaktBatteryLevelValue).toHaveText("100%") + }) + + it("Connect 2nd device", async () => { + E2EMockClient.mockResponse({ + path: "path-2", + body: overviewDataWithOneSimCard2nd, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: "path-2", + serialNumber: secondSerialNumber, + }) + + await browser.pause(6000) + }) + + it("Check Drawer Modal and Switch to 2nd device", async () => { + const deviceSelectDrawer = await drawerPage.deviceSelectDrawer + await expect(deviceSelectDrawer).toBeDisplayed() + + const deviceImageOnDrawer = await drawerPage.deviceImageOnDrawer + await expect(deviceImageOnDrawer).toBeDisplayed() + + const firstDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + firstSerialNumber + ) + await expect(firstDeviceOnDrawer).toBeDisplayed() + const secondDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + secondSerialNumber + ) + await expect(secondDeviceOnDrawer).toBeDisplayed() + await secondDeviceOnDrawer.waitForClickable() + await secondDeviceOnDrawer.click() + }) + + it("Verify Overview Page for 2nd device", async () => { + const kompaktImage = await OverviewKompaktPage.kompaktImage + await expect(kompaktImage).toBeDisplayed() + await expect(kompaktImage).toHaveAttribute("src", kompaktImageRegex) + + const kompaktOsVersion = await OverviewKompaktPage.kompaktOsVersion + await expect(kompaktOsVersion).toBeDisplayed() + + const kompaktSimCard1Subtext = + await OverviewKompaktPage.kompaktSimCard1Subtext + await expect(kompaktSimCard1Subtext).toHaveText("SIM 1") + + const kompaktNetworkName = await OverviewKompaktPage.kompaktNetworkName + await expect(kompaktNetworkName).toBeDisplayed() + await expect(kompaktNetworkName).toHaveText("Play") + + const kompaktBatteryLevelValue = + await OverviewKompaktPage.kompaktBatteryLevelValue + await expect(kompaktBatteryLevelValue).toBeDisplayed() + await expect(kompaktBatteryLevelValue).toHaveText("40%") + }) + + it("Verify Select Connected Devices, click on it and select 1st Kompakt", async () => { + const selectConnectedDevices = await overviewPage.selectConnectedDevices + await selectConnectedDevices.waitForClickable() + await expect(selectConnectedDevices).toHaveText("2") + await selectConnectedDevices.click() + + const firstDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + firstSerialNumber + ) + await expect(firstDeviceOnDrawer).toBeDisplayed() + await firstDeviceOnDrawer.waitForClickable() + await firstDeviceOnDrawer.click() + }) + + it("Disconnect the devices and check if Welcome Page is present", async () => { + E2EMockClient.removeDevice("path-1") + E2EMockClient.removeDevice("path-2") + + const homeHeader = await HomePage.homeHeader + await homeHeader.waitForDisplayed() + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/settings/mc-version-check-for-updates-offline.e2e.ts b/apps/mudita-center-e2e/src/specs/settings/mc-version-check-for-updates-offline.e2e.ts index 08384d3792..8d48cfc2d7 100644 --- a/apps/mudita-center-e2e/src/specs/settings/mc-version-check-for-updates-offline.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/settings/mc-version-check-for-updates-offline.e2e.ts @@ -5,19 +5,45 @@ import SettingsPage from "../../page-objects/settings.page" import NavigationTabs from "../../page-objects/tabs.page" -import ModalPage from "../../page-objects/mc-update-modal.page" +import ModalPage from "../../page-objects/modal.page" +import McUpdateModalPage from "../../page-objects/mc-update-modal.page" import HomePage from "../../page-objects/home.page" -import TestHelper from "../../helpers/tests.helper" +import testsHelper from "../../helpers/tests.helper" import dns from "node:dns" +import screenshotHelper from "../../helpers/screenshot.helper" +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" describe("Checking for Mudita Center updates", () => { before(async function () { - if (TestHelper.isLinux()) { + if (testsHelper.isLinux()) { this.skip() } - dns.setDefaultResultOrder("ipv4first") - await browser.throttle("offline") + E2EMockClient.connect() + //wait for a connection to be established + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + + // Clear browser cache + await browser.deleteAllCookies() + await browser.execute("window.localStorage.clear();") + await browser.execute("window.sessionStorage.clear();") + + // Switch to offline mode before starting the tests + await browser.setNetworkConditions({ + offline: true, + latency: 0, + download_throughput: 0, + upload_throughput: 0, + }) + + // Add a small delay to ensure network conditions are applied + await browser.pause(1000) + + // Verify network conditions + const isOnline = await testsHelper.isOnline() + await expect(isOnline).toBeFalsy() const notNowButton = await HomePage.notNowButton await notNowButton.waitForDisplayed() @@ -32,17 +58,6 @@ describe("Checking for Mudita Center updates", () => { const aboutTab = await SettingsPage.aboutTab await aboutTab.waitForDisplayed() await aboutTab.click() - - const aboutCheckForUpdateFailedLabel = - await SettingsPage.aboutCheckForUpdateFailedLabel - await browser.executeAsync((done) => { - setTimeout(done, 10000) - }) - - await expect(aboutCheckForUpdateFailedLabel).toBeDisplayed() - await expect(aboutCheckForUpdateFailedLabel).toHaveText( - "Checking for updates failed" - ) }) it("Check 'Check for updates' button", async () => { @@ -61,14 +76,48 @@ describe("Checking for Mudita Center updates", () => { it("Check for updates", async () => { const checkingFailedUpdateSubtitle = - await ModalPage.checkingFailedUpdateSubtitle + await McUpdateModalPage.checkingFailedUpdateSubtitle await expect(checkingFailedUpdateSubtitle).toBeDisplayed() await expect(checkingFailedUpdateSubtitle).toHaveText("Checking failed") - const checkingFailedUpdateBody = await ModalPage.checkingFailedUpdateBody + const checkingFailedUpdateBody = + await McUpdateModalPage.checkingFailedUpdateBody await expect(checkingFailedUpdateBody).toBeDisplayed() await expect(checkingFailedUpdateBody).toHaveText( - "Opps, something went wrong. \nPlease check your internet connection" + "Oops, something went wrong. \nPlease check your internet connection" ) + + await ModalPage.closeModalButtonClick() + }) + it("Check Settings -> About checking failed label", async () => { + screenshotHelper.makeViewScreenshot() + const aboutCheckForUpdateFailedLabel = + await SettingsPage.aboutCheckForUpdateFailedLabel + + await expect(aboutCheckForUpdateFailedLabel).toBeDisplayed() + + await expect(aboutCheckForUpdateFailedLabel).toHaveText( + "Checking for updates failed" + ) + }) + + after(async () => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + + // Switch back to online mode after finishing the tests + await browser.setNetworkConditions({ + offline: false, + latency: 0, + download_throughput: -1, + upload_throughput: -1, + }) + + // Add a small delay to ensure network conditions are applied + await browser.pause(1000) + + // Verify network conditions + const isOnline = await testsHelper.isOnline() + await expect(isOnline).toBeTruthy() }) }) diff --git a/apps/mudita-center-e2e/src/specs/settings/privacy-policy.e2e.ts b/apps/mudita-center-e2e/src/specs/settings/privacy-policy.e2e.ts index 1e0ffdebe1..791986c667 100644 --- a/apps/mudita-center-e2e/src/specs/settings/privacy-policy.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/settings/privacy-policy.e2e.ts @@ -8,6 +8,8 @@ import NavigationTabs from "../../page-objects/tabs.page" import HomePage from "../../page-objects/home.page" import modalPrivacyPolicyPage from "../../page-objects/modal-privacy-policy.page" import ModalPage from "../../page-objects/modal.page" +import { sleep } from "../../helpers/sleep.helper" +import testsHelper from "../../helpers/tests.helper" describe("Checking Privacy Policy", () => { before(async function () { @@ -35,6 +37,10 @@ describe("Checking Privacy Policy", () => { }) it("Check Privacy Policy 'LEARN MORE' button", async () => { + if(testsHelper.isLinux()){ + sleep(5000) + } + const aboutPrivacyPolicyButton = await SettingsPage.aboutPrivacyPolicyButton await expect(aboutPrivacyPolicyButton).toHaveText("LEARN MORE") await aboutPrivacyPolicyButton.click() diff --git a/apps/mudita-center-e2e/src/specs/settings/terms-of-service.e2e.ts b/apps/mudita-center-e2e/src/specs/settings/terms-of-service.e2e.ts index b39ab8f779..ab8c6c3fa9 100644 --- a/apps/mudita-center-e2e/src/specs/settings/terms-of-service.e2e.ts +++ b/apps/mudita-center-e2e/src/specs/settings/terms-of-service.e2e.ts @@ -8,6 +8,8 @@ import NavigationTabs from "../../page-objects/tabs.page" import HomePage from "../../page-objects/home.page" import ModalTermsOfServicePage from "../../page-objects/modal-terms-of-service.page" import ModalPage from "../../page-objects/modal.page" +import { sleep } from "../../helpers/sleep.helper" +import testsHelper from "../../helpers/tests.helper" describe("Checking Terms of service", () => { before(async function () { @@ -35,8 +37,13 @@ describe("Checking Terms of service", () => { }) it("Check Terms of service 'LEARN MORE' button", async () => { + if(testsHelper.isLinux()){ + sleep(5000) + } + const aboutTermsOfServiceButton = await SettingsPage.aboutTermsOfServiceButton + await expect(aboutTermsOfServiceButton).toHaveText("LEARN MORE") await aboutTermsOfServiceButton.click() diff --git a/apps/mudita-center-e2e/src/specs/stress-tests/connected-devices-stress-test.ts b/apps/mudita-center-e2e/src/specs/stress-tests/connected-devices-stress-test.ts new file mode 100644 index 0000000000..8fdb23453c --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/stress-tests/connected-devices-stress-test.ts @@ -0,0 +1,232 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + overviewDataWithOneSimCard, + overviewDataWithOneSimCard2nd, + overviewDataWithOneSimCard3rd, + overviewDataWithOneSimCard4th, + overviewDataWithOneSimCard5th, + overviewDataWithOneSimCard6th, +} from "../../../../../libs/e2e-mock/responses/src" +import OverviewKompaktPage from "../../page-objects/overview-kompakt.page" +import HomePage from "../../page-objects/home.page" +import { kompaktImageRegex } from "../../consts/regex-const" +import selectDevicePage from "../../page-objects/select-device.page" + +describe("Kompakt switching devices", () => { + const firstSerialNumber = "KOM1234567890" + const secondSerialNumber = "KOM1234567892" + const thirdSerialNumber = "KOM1234567893" + const fourthSerialNumber = "KOM1234567894" + const fifthSerialNumber = "KOM1234567895" + const sixthSerialNumber = "KOM1234567896" + + before(async () => { + E2EMockClient.connect() + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect 1,2 Kompakt devices", async () => { + const devices = [ + { + path: "path-1", + body: overviewDataWithOneSimCard, + serialNumber: firstSerialNumber, + }, + { + path: "path-2", + body: overviewDataWithOneSimCard2nd, + serialNumber: secondSerialNumber, + }, + ] + + const mockResponses = devices.map((device) => { + E2EMockClient.mockResponse({ + path: device.path, + body: device.body, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + return E2EMockClient.addDevice({ + path: device.path, + serialNumber: device.serialNumber, + }) + }) + await Promise.all(mockResponses) + await browser.pause(6000) + }) + + it("Check Select Device Modal and verify Devices 1 and 2", async () => { + const selectADeviceToContinueTitle = + await selectDevicePage.selectADeviceToContinueTitle + await expect(selectADeviceToContinueTitle).toHaveText( + "Select a device to continue" + ) + + const availableDevices = selectDevicePage.availableDevices + await expect(availableDevices).toBeDisplayed() + + const firstDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(1) + const secondDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(2) + + await expect(firstDeviceOnSelectModal).toBeDisplayed() + await expect(secondDeviceOnSelectModal).toBeDisplayed() + + const selectDeviceModalSerialNumbers = + selectDevicePage.selectDeviceSerialNumber + const selectDeviceModalNames = selectDevicePage.selectDeviceName + + const firstDeviceSerialNumber = + await selectDeviceModalSerialNumbers[0].getText() + await expect(firstDeviceSerialNumber).toEqual(firstSerialNumber) + const firstDeviceName = await selectDeviceModalNames[0] + await expect(firstDeviceName).toHaveText("Kompakt") + + const secondDeviceSerialNumber = + await selectDeviceModalSerialNumbers[1].getText() + await expect(secondDeviceSerialNumber).toEqual(secondSerialNumber) + const secondDeviceName = await selectDeviceModalNames[1] + await expect(secondDeviceName).toHaveText("Kompakt") + }) + + it("Connect 3,4,5,6 Kompakt devices", async () => { + const devices = [ + { + path: "path-3", + body: overviewDataWithOneSimCard3rd, + serialNumber: thirdSerialNumber, + }, + { + path: "path-4", + body: overviewDataWithOneSimCard4th, + serialNumber: fourthSerialNumber, + }, + { + path: "path-5", + body: overviewDataWithOneSimCard5th, + serialNumber: fifthSerialNumber, + }, + { + path: "path-6", + body: overviewDataWithOneSimCard6th, + serialNumber: sixthSerialNumber, + }, + ] + + for (const device of devices) { + E2EMockClient.mockResponse({ + path: device.path, + body: device.body, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: device.path, + serialNumber: device.serialNumber, + }) + + await browser.pause(6000) + } + }) + + it("Verify Devices 3, 4, 5, 6", async () => { + const thirdDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(1) + const fourthDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(2) + + await expect(thirdDeviceOnSelectModal).toBeDisplayed() + await expect(fourthDeviceOnSelectModal).toBeDisplayed() + + const selectDeviceModalSerialNumbers = + selectDevicePage.selectDeviceSerialNumber + const selectDeviceModalNames = selectDevicePage.selectDeviceName + + const thirdDeviceSerialNumber = + await selectDeviceModalSerialNumbers[2].getText() + await expect(thirdDeviceSerialNumber).toEqual(thirdSerialNumber) + const thirdDeviceName = await selectDeviceModalNames[2] + await expect(thirdDeviceName).toHaveText("Kompakt") + + const fourthDeviceSerialNumber = + await selectDeviceModalSerialNumbers[3].getText() + await expect(fourthDeviceSerialNumber).toEqual(fourthSerialNumber) + const fourthDeviceName = await selectDeviceModalNames[3] + await expect(fourthDeviceName).toHaveText("Kompakt") + + const fifthDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(1) + const sixthDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(2) + + await expect(fifthDeviceOnSelectModal).toBeDisplayed() + await expect(sixthDeviceOnSelectModal).toBeDisplayed() + + const fifthDeviceSerialNumber = + await selectDeviceModalSerialNumbers[4].getText() + await expect(fifthDeviceSerialNumber).toEqual(fifthSerialNumber) + const fifthDeviceName = await selectDeviceModalNames[4] + await expect(fifthDeviceName).toHaveText("Kompakt") + + const sixthDeviceSerialNumber = + await selectDeviceModalSerialNumbers[5].getText() + await expect(sixthDeviceSerialNumber).toEqual(sixthSerialNumber) + const sixthDeviceName = await selectDeviceModalNames[5] + await expect(sixthDeviceName).toHaveText("Kompakt") + }) + + it("Switch to 6th device", async () => { + const sixthDeviceOnSelectModal = + await selectDevicePage.getDeviceOnSelectModal(6) + + await expect(sixthDeviceOnSelectModal).toBeDisplayed() + await sixthDeviceOnSelectModal.waitForClickable() + await sixthDeviceOnSelectModal.click() + }) + + it("Verify Overview Page for 6th device", async () => { + const kompaktImage = await OverviewKompaktPage.kompaktImage + await expect(kompaktImage).toBeDisplayed() + await expect(kompaktImage).toHaveAttribute("src", kompaktImageRegex) + + const kompaktOsVersion = await OverviewKompaktPage.kompaktOsVersion + await expect(kompaktOsVersion).toBeDisplayed() + await expect(kompaktOsVersion).toHaveText("Mudita OS") + + const kompaktSimCard1Subtext = + await OverviewKompaktPage.kompaktSimCard1Subtext + await expect(kompaktSimCard1Subtext).toHaveText("SIM 1") + + const kompaktNetworkName = await OverviewKompaktPage.kompaktNetworkName + await expect(kompaktNetworkName).toBeDisplayed() + await expect(kompaktNetworkName).toHaveText("Telia") + + const kompaktBatteryLevelValue = + await OverviewKompaktPage.kompaktBatteryLevelValue + await expect(kompaktBatteryLevelValue).toBeDisplayed() + await expect(kompaktBatteryLevelValue).toHaveText("20%") + }) + + it("Disconnect the devices and check if News page is present", async () => { + E2EMockClient.removeDevice("path-1") + E2EMockClient.removeDevice("path-2") + E2EMockClient.removeDevice("path-3") + E2EMockClient.removeDevice("path-4") + E2EMockClient.removeDevice("path-5") + E2EMockClient.removeDevice("path-6") + + const homeHeader = await HomePage.homeHeader + await homeHeader.waitForDisplayed() + await expect(homeHeader).toHaveText("Welcome to Mudita Center") + }) +}) diff --git a/apps/mudita-center-e2e/src/specs/stress-tests/device-drawer-stress-test.ts b/apps/mudita-center-e2e/src/specs/stress-tests/device-drawer-stress-test.ts new file mode 100644 index 0000000000..0c6c5a17cb --- /dev/null +++ b/apps/mudita-center-e2e/src/specs/stress-tests/device-drawer-stress-test.ts @@ -0,0 +1,248 @@ +import { E2EMockClient } from "../../../../../libs/e2e-mock/client/src" +import { + overviewDataWithOneSimCard, + overviewDataWithOneSimCard2nd, + overviewDataWithOneSimCard3rd, + overviewDataWithOneSimCard4th, + overviewDataWithOneSimCard5th, + overviewDataWithOneSimCard6th, +} from "../../../../../libs/e2e-mock/responses/src" +import OverviewKompaktPage from "../../page-objects/overview-kompakt.page" +import HomePage from "../../page-objects/home.page" +import overviewPage from "../../page-objects/overview.page" +import drawerPage from "../../page-objects/drawer.page" + +describe("Kompakt switching devices", () => { + const firstSerialNumber = "KOM1234567890" + const secondSerialNumber = "KOM1234567892" + const thirdSerialNumber = "KOM1234567893" + const fourthSerialNumber = "KOM1234567894" + const fifthSerialNumber = "KOM1234567895" + const sixthSerialNumber = "KOM1234567896" + + before(async () => { + E2EMockClient.connect() + await browser.waitUntil(() => { + return E2EMockClient.checkConnection() + }) + }) + + after(() => { + E2EMockClient.stopServer() + E2EMockClient.disconnect() + }) + + it("Connect 1,2 Kompakt devices", async () => { + const devices = [ + { + path: "path-1", + body: overviewDataWithOneSimCard, + serialNumber: firstSerialNumber, + }, + { + path: "path-2", + body: overviewDataWithOneSimCard2nd, + serialNumber: secondSerialNumber, + }, + ] + + for (const device of devices) { + E2EMockClient.mockResponse({ + path: device.path, + body: device.body, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: device.path, + serialNumber: device.serialNumber, + }) + + await browser.pause(6000) + } + }) + + it("Verify Devices 1 and 2 on Drawer and check their Serial Numbers", async () => { + const deviceSelectDrawer = await drawerPage.deviceSelectDrawer + await expect(deviceSelectDrawer).toBeDisplayed() + + const deviceImageOnDrawer = await drawerPage.deviceImageOnDrawer + await expect(deviceImageOnDrawer).toBeDisplayed() + + const firstDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + firstSerialNumber + ) + const secondDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + secondSerialNumber + ) + await expect(firstDeviceOnDrawer).toBeDisplayed() + await expect(secondDeviceOnDrawer).toBeDisplayed() + + const drawerSerialNumbers = await drawerPage.drawerDeviceSerialNumber + + const devices = [ + { serialNumber: firstSerialNumber, index: 0 }, + { serialNumber: secondSerialNumber, index: 1 }, + ] + + for (const device of devices) { + const deviceSerialNumber = await drawerSerialNumbers[ + device.index + ].getText() + await expect(deviceSerialNumber).toEqual(device.serialNumber) + } + }) + + it("Connect 3rd Kompakt device", async () => { + E2EMockClient.mockResponse({ + path: "path-3", + body: overviewDataWithOneSimCard3rd, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: "path-3", + serialNumber: thirdSerialNumber, + }) + + await browser.pause(6000) + const menuItem = await $(`//a[@href="#/generic/mc-overview"]`) + + await menuItem.waitForDisplayed({ timeout: 10000 }) + await expect(menuItem).toBeDisplayed() + }) + + it("Verify Device 3 on the Drawer and check the Serial Number", async () => { + const deviceSelectDrawer = await drawerPage.deviceSelectDrawer + await expect(deviceSelectDrawer).toBeDisplayed() + + const deviceImageOnDrawer = await drawerPage.deviceImageOnDrawer + await expect(deviceImageOnDrawer).toBeDisplayed() + + const thirdDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + thirdSerialNumber + ) + + await expect(thirdDeviceOnDrawer).toBeDisplayed() + + const drawerSerialNumbers = drawerPage.drawerDeviceSerialNumber + + const thirdDrawerDeviceSerialNumber = await drawerSerialNumbers[2].getText() + await expect(thirdDrawerDeviceSerialNumber).toEqual(thirdSerialNumber) + }) + + it("Connect 4,5,6 Kompakt devices", async () => { + const devices = [ + { + path: "path-4", + body: overviewDataWithOneSimCard4th, + serialNumber: fourthSerialNumber, + }, + { + path: "path-5", + body: overviewDataWithOneSimCard5th, + serialNumber: fifthSerialNumber, + }, + { + path: "path-6", + body: overviewDataWithOneSimCard6th, + serialNumber: sixthSerialNumber, + }, + ] + + for (const device of devices) { + E2EMockClient.mockResponse({ + path: device.path, + body: device.body, + endpoint: "FEATURE_DATA", + method: "GET", + status: 200, + }) + E2EMockClient.addDevice({ + path: device.path, + serialNumber: device.serialNumber, + }) + + await browser.pause(6000) + } + }) + + it("Verify Devices 4,5 and 6 on Drawer and check their Serial Numbers, scroll down and select 6th Kompakt", async () => { + const deviceSelectDrawer = await drawerPage.deviceSelectDrawer + await expect(deviceSelectDrawer).toBeDisplayed() + + const deviceImageOnDrawer = await drawerPage.deviceImageOnDrawer + await expect(deviceImageOnDrawer).toBeDisplayed() + + const fourthDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + fourthSerialNumber + ) + const fifthDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + fifthSerialNumber + ) + const sixthDeviceOnDrawer = await drawerPage.getDeviceOnDrawer( + sixthSerialNumber + ) + await expect(fourthDeviceOnDrawer).toBeDisplayed() + await expect(fifthDeviceOnDrawer).toBeDisplayed() + await expect(sixthDeviceOnDrawer).toBeDisplayed() + + const drawerSerialNumbers = await drawerPage.drawerDeviceSerialNumber + const drawerDeviceNames = await drawerPage.drawerDeviceName + + const devices = [ + { serialNumber: fourthSerialNumber, name: "Kompakt", index: 3 }, + { serialNumber: fifthSerialNumber, name: "Kompakt", index: 4 }, + { serialNumber: sixthSerialNumber, name: "Kompakt", index: 5 }, + ] + + for (const device of devices) { + const deviceSerialNumber = await drawerSerialNumbers[ + device.index + ].getText() + await expect(deviceSerialNumber).toEqual(device.serialNumber) + + const deviceName = await drawerDeviceNames[device.index] + await expect(deviceName).toHaveText(device.name) + } + + await browser.execute(() => { + window.scrollBy(0, 500) + }) + + await browser.pause(1000) + + await sixthDeviceOnDrawer.waitForClickable() + await sixthDeviceOnDrawer.click() + }) + + it("Verify 6th Kompakt with new Serial Number and click Show connected devices", async () => { + const serialNumberLabel = await OverviewKompaktPage.serialNumberLabel + const serialNumberValue = await OverviewKompaktPage.serialNumberValue + await expect(serialNumberLabel).toHaveText("Serial number") + await expect(serialNumberValue).toHaveText( + overviewDataWithOneSimCard6th.summary.about.serialNumber.text.toString() + ) + const selectConnectedDevices = await overviewPage.selectConnectedDevices + await selectConnectedDevices.waitForClickable() + await expect(selectConnectedDevices).toHaveText("6") + await selectConnectedDevices.click() + }) + + it("Disconnect the devices and check if Welcome Page is present", async () => { + E2EMockClient.removeDevice("path-1") + E2EMockClient.removeDevice("path-2") + E2EMockClient.removeDevice("path-3") + E2EMockClient.removeDevice("path-4") + E2EMockClient.removeDevice("path-5") + E2EMockClient.removeDevice("path-6") + + const homeHeader = await HomePage.homeHeader + await homeHeader.waitForDisplayed() + }) +}) + +const devicePaths = ["path-1", "path-2", "path-3", "path-4", "path-5", "path-6"] +devicePaths.forEach((path) => E2EMockClient.removeDevice(path)) diff --git a/apps/mudita-center-e2e/src/test-filenames/consts/test-filenames.const.ts b/apps/mudita-center-e2e/src/test-filenames/consts/test-filenames.const.ts index 10e4e12dc3..0ab7dc591e 100644 --- a/apps/mudita-center-e2e/src/test-filenames/consts/test-filenames.const.ts +++ b/apps/mudita-center-e2e/src/test-filenames/consts/test-filenames.const.ts @@ -18,5 +18,14 @@ export enum TestFilesPaths { privacyPolicyTest = "src/specs/settings/privacy-policy.e2e.ts", licenseTest = "src/specs/settings/license.e2e.ts", helpWindowCheckOfflineTest = "src/specs/help/help-window-check-offline.e2e.ts", + mcHomePageForceUpdateTest = "src/specs/overview/e2e-mock-mc-force-update-available.e2e.ts", + mcHomePageForceUpdateErrorTest = "src/specs/overview/e2e-mock-mc-force-update-error.e2e.ts", + mcHomePageSoftUpdateTest = "src/specs/overview/e2e-mock-mc-soft-update-available.e2e.ts", + mcHomePageSoftUpdateErrorTest = "src/specs/overview/e2e-mock-mc-soft-update-error.e2e.ts", + kompaktOverview = "src/specs/overview/kompakt-overview.ts", + kompaktSwitchingDevices = "src/specs/overview/kompakt-switching-devices.ts", + kompaktAbout = "src/specs/overview/kompakt-about.ts", + kompaktConnectedDevicesModalStressTest = "src/specs/stress-tests/connected-devices-stress-test.ts", + kompaktDrawerStressTest = "src/specs/stress-tests/device-drawer-stress-test.ts", } export const toRelativePath = (path: string) => `./${path}` diff --git a/apps/mudita-center-e2e/wdio.conf.ts b/apps/mudita-center-e2e/wdio.conf.ts index e51198e7c5..2da0d93030 100644 --- a/apps/mudita-center-e2e/wdio.conf.ts +++ b/apps/mudita-center-e2e/wdio.conf.ts @@ -63,29 +63,44 @@ export const config: Options.Testrunner = { toRelativePath(TestFilesPaths.termsOfServiceTest), toRelativePath(TestFilesPaths.backupLocationTest), toRelativePath(TestFilesPaths.mcCheckForUpdatesOfflineTest), - toRelativePath(TestFilesPaths.e2eMockSample), toRelativePath(TestFilesPaths.privacyPolicyTest), toRelativePath(TestFilesPaths.licenseTest), toRelativePath(TestFilesPaths.helpWindowCheckOfflineTest), + toRelativePath(TestFilesPaths.kompaktOverview), + toRelativePath(TestFilesPaths.kompaktSwitchingDevices), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateErrorTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateErrorTest), + toRelativePath(TestFilesPaths.kompaktAbout), + toRelativePath(TestFilesPaths.kompaktConnectedDevicesModalStressTest), + toRelativePath(TestFilesPaths.kompaktDrawerStressTest), ], suites: { standalone: [ - toRelativePath(TestFilesPaths.helpWindowCheckTest), - toRelativePath(TestFilesPaths.mcCheckForUpdatesTest), - toRelativePath(TestFilesPaths.homePageTestDeviceNotConnectedTest), + //toRelativePath(TestFilesPaths.helpWindowCheckTest), + //toRelativePath(TestFilesPaths.homePageTestDeviceNotConnectedTest), toRelativePath(TestFilesPaths.newsPageOnlineTest), toRelativePath(TestFilesPaths.termsOfServiceTest), toRelativePath(TestFilesPaths.backupLocationTest), - toRelativePath(TestFilesPaths.mcCheckForUpdatesOfflineTest), - toRelativePath(TestFilesPaths.homePageTestDeviceNotConnectedTest), - toRelativePath(TestFilesPaths.newsPageOnlineTest), - toRelativePath(TestFilesPaths.termsOfServiceTest), - toRelativePath(TestFilesPaths.e2eMockSample), toRelativePath(TestFilesPaths.privacyPolicyTest), toRelativePath(TestFilesPaths.licenseTest), - toRelativePath(TestFilesPaths.helpWindowCheckOfflineTest), ], - mock: [toRelativePath(TestFilesPaths.e2eMockSample)], + mock: [ + toRelativePath(TestFilesPaths.mcCheckForUpdatesTest), + toRelativePath(TestFilesPaths.mcCheckForUpdatesOfflineTest), + toRelativePath(TestFilesPaths.newsPageOfflineTest), + //toRelativePath(TestFilesPaths.helpWindowCheckOfflineTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateErrorTest), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateErrorTest), + toRelativePath(TestFilesPaths.kompaktOverview), + toRelativePath(TestFilesPaths.kompaktSwitchingDevices), + toRelativePath(TestFilesPaths.kompaktAbout), + toRelativePath(TestFilesPaths.kompaktConnectedDevicesModalStressTest), + toRelativePath(TestFilesPaths.kompaktDrawerStressTest), + ], multidevicePureHarmony: [], multideviceSingleHarmony: [], multideviceSinglePure: [], @@ -97,17 +112,26 @@ export const config: Options.Testrunner = { pure: [toRelativePath(TestFilesPaths.messagesInAppNavigationTest)], kompakt: [], deviceUpdate: [], - cicd: [ - toRelativePath(TestFilesPaths.helpWindowCheckTest), + cicdStandalone: [ + //toRelativePath(TestFilesPaths.helpWindowCheckTest), + //toRelativePath(TestFilesPaths.homePageTestDeviceNotConnectedTest), + toRelativePath(TestFilesPaths.newsPageOnlineTest), + toRelativePath(TestFilesPaths.termsOfServiceTest), + ], + cicdMock: [ toRelativePath(TestFilesPaths.mcCheckForUpdatesTest), toRelativePath(TestFilesPaths.mcCheckForUpdatesOfflineTest), - toRelativePath(TestFilesPaths.homePageTestDeviceNotConnectedTest), - toRelativePath(TestFilesPaths.newsPageOnlineTest), toRelativePath(TestFilesPaths.newsPageOfflineTest), - toRelativePath(TestFilesPaths.termsOfServiceTest), - toRelativePath(TestFilesPaths.privacyPolicyTest), - toRelativePath(TestFilesPaths.licenseTest), - toRelativePath(TestFilesPaths.helpWindowCheckOfflineTest), + //toRelativePath(TestFilesPaths.helpWindowCheckOfflineTest), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageForceUpdateErrorTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateTest), + toRelativePath(TestFilesPaths.mcHomePageSoftUpdateErrorTest), + toRelativePath(TestFilesPaths.kompaktOverview), + toRelativePath(TestFilesPaths.kompaktSwitchingDevices), + toRelativePath(TestFilesPaths.kompaktAbout), + toRelativePath(TestFilesPaths.kompaktConnectedDevicesModalStressTest), + toRelativePath(TestFilesPaths.kompaktDrawerStressTest), ], }, // Patterns to exclude. diff --git a/apps/mudita-center/package-lock.json b/apps/mudita-center/package-lock.json index dcbbc9011a..c6474fb501 100644 --- a/apps/mudita-center/package-lock.json +++ b/apps/mudita-center/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mudita/mudita-center-app", - "version": "2.3.1", + "version": "2.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@mudita/mudita-center-app", - "version": "2.3.1", + "version": "2.4.0", "license": "GPL-3.0", "dependencies": { "serialport": "10.1.0" diff --git a/apps/mudita-center/package.json b/apps/mudita-center/package.json index 765341d9c3..c7a5e560e6 100644 --- a/apps/mudita-center/package.json +++ b/apps/mudita-center/package.json @@ -1,6 +1,6 @@ { "name": "mudita-center", - "version": "2.3.1", + "version": "2.4.0", "description": "Mudita Center", "main": "./dist/main.js", "productName": "Mudita Center", @@ -27,14 +27,14 @@ "fonts:download": "node ../../scripts/downloadFonts.js", "copy-static-dependencies": "node ../../scripts/copy-static-sql-js-dependencies.js", "news:download": "ts-node ../../scripts/downloadNews.ts", - "help:download": "ts-node ../../scripts/downloadHelpItems.ts", + "help-v2:download": "ts-node ../../scripts/downloadHelpV2.ts", "app-configuration:download": "ts-node ../../scripts/download-configuration.ts", "UTILITY/AUTO COMMANDS": "=================================================", "prestart": "npm run build", "posttranslations:sync": "npm run translations:sort", "posttranslations:sort": "prettier --write src/**/*.json", "posttest:coverage": "prettier --write ./jest.coverage.json", - "postsetup": "npm run fonts:download && npm run news:download && npm run app-configuration:download && npm run copy-static-dependencies" + "postsetup": "npm run fonts:download && npm run news:download && npm run app-configuration:download && npm run copy-static-dependencies && npm run help-v2:download" }, "build": { "productName": "Mudita Center", diff --git a/apps/mudita-center/src/main.ts b/apps/mudita-center/src/main.ts index 3ee2751737..e6b9ce6cbf 100644 --- a/apps/mudita-center/src/main.ts +++ b/apps/mudita-center/src/main.ts @@ -24,18 +24,6 @@ import registerWriteGzipListener from "Core/__deprecated__/main/functions/regist import registerRmdirListener from "Core/__deprecated__/main/functions/register-rmdir-listener" import registerArchiveFilesListener from "Core/__deprecated__/main/functions/register-archive-files-listener" import createDownloadListenerRegistrar from "Core/__deprecated__/main/functions/create-download-listener-registrar" -import { - registerDownloadHelpHandler, - removeDownloadHelpHandler, -} from "Core/__deprecated__/main/functions/download-help-handler" -import { - registerSetHelpStoreHandler, - removeSetHelpStoreHandler, -} from "Core/__deprecated__/main/functions/set-help-store-handler" -import { - registerGetHelpStoreHandler, - removeGetHelpStoreHandler, -} from "Core/__deprecated__/main/functions/get-help-store-handler" import { GoogleAuthActions } from "Core/__deprecated__/common/enums/google-auth-actions.enum" import { authServerPort, @@ -44,30 +32,29 @@ import { } from "Core/__deprecated__/main/auth-server" import logger from "Core/__deprecated__/main/utils/logger" import { - Scope, clientId, redirectUrl, + Scope, TokenRequester, } from "generic-view/store" import { OutlookAuthActions } from "Core/__deprecated__/common/enums/outlook-auth-actions.enum" import { + DEFAULT_WINDOWS_SIZE, GOOGLE_AUTH_WINDOW_SIZE, WINDOW_SIZE, - DEFAULT_WINDOWS_SIZE, } from "Core/__deprecated__/main/config" import { URL_MAIN, URL_OVERVIEW, } from "Core/__deprecated__/renderer/constants/urls" import { Mode } from "Core/__deprecated__/common/enums/mode.enum" -import { HelpActions } from "Core/__deprecated__/common/enums/help-actions.enum" import { AboutActions } from "Core/__deprecated__/common/enums/about-actions.enum" import { PureSystemActions } from "Core/__deprecated__/common/enums/pure-system-actions.enum" import { BrowserActions } from "Core/__deprecated__/common/enums/browser-actions.enum" import { createMetadataStore, - MetadataStore, MetadataInitializer, + MetadataStore, registerMetadataAllGetValueListener, registerMetadataGetValueListener, registerMetadataSetValueListener, @@ -77,10 +64,17 @@ import { createSettingsService } from "Core/settings/containers/settings.contain import { ApplicationModule } from "Core/core/application.module" import registerExternalUsageDevice from "Core/device/listeners/register-external-usage-device.listner" import installExtension, { - REDUX_DEVTOOLS, REACT_DEVELOPER_TOOLS, + REDUX_DEVTOOLS, } from "electron-devtools-installer" -import { AppEvents, callRenderer, getMainAppWindow } from "shared/utils" +import { + AppEvents, + callRenderer, + getMainAppWindow, + openDevToolsOnceDomReady, + preventDefaultShortcuts, + registerShortcuts, +} from "shared/utils" import { mockServiceEnabled, startServer, stopServer } from "e2e-mock-server" // AUTO DISABLED - fix me if you like :) @@ -99,7 +93,6 @@ if (mockServiceEnabled) { logger.info("Starting the app!") let win: BrowserWindow | null -let helpWindow: BrowserWindow | null = null let googleAuthWindow: BrowserWindow | null = null let outlookAuthWindow: BrowserWindow | null = null const licenseWindow: BrowserWindow | null = null @@ -184,12 +177,6 @@ const createWindow = async () => { require("@electron/remote/main").enable(win.webContents) win.removeMenu() - win.webContents.on("before-input-event", (event, input) => { - if ((input.control || input.meta) && input.key.toLowerCase() === "r") { - event.preventDefault() - } - }) - win.on("closed", () => { win = null app.exit() @@ -250,26 +237,9 @@ const createWindow = async () => { } }) - if (productionEnvironment) { - win.webContents.once("dom-ready", () => { - appModules.lateInitialization() - }) - } else { - // Open DevTools, see https://github.com/electron/electron/issues/12438 for why we wait for dom-ready - win.webContents.once("dom-ready", () => { - // AUTO DISABLED - fix me if you like :) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - win!.webContents.openDevTools() - appModules.lateInitialization() - }) - - win.webContents.once("dom-ready", () => { - win!.webContents.once("devtools-opened", () => { - win!.focus() - }) - win!.webContents.openDevTools() - }) - } + win.webContents.once("dom-ready", () => { + appModules.lateInitialization() + }) logger.updateMetadata() } @@ -281,6 +251,12 @@ if (!gotTheLock) { // eslint-disable-next-line @typescript-eslint/no-misused-promises app.on("ready", createWindow) + app.on("browser-window-created", (_event, window) => { + preventDefaultShortcuts(window) + registerShortcuts(window) + openDevToolsOnceDomReady(window) + }) + app.on("before-quit", () => { stopServer() }) @@ -296,66 +272,6 @@ if (!gotTheLock) { }) } -ipcMain.answerRenderer(HelpActions.OpenWindow, () => { - const title = "Mudita Center - Help" - if (helpWindow === null) { - helpWindow = new BrowserWindow( - getWindowOptions({ - width: DEFAULT_WINDOWS_SIZE.width, - height: DEFAULT_WINDOWS_SIZE.height, - title, - }) - ) - // FIXME: electron v12 added changes to the remote module. This module has many subtle pitfalls. - // There is almost always a better way to accomplish your task than using this module. - // You can read more in https://github.com/electron/remote#migrating-from-remote - require("@electron/remote/main").enable(helpWindow.webContents) - helpWindow.removeMenu() - - helpWindow.on("closed", () => { - removeDownloadHelpHandler() - removeSetHelpStoreHandler() - removeGetHelpStoreHandler() - helpWindow = null - void ipcMain.callRenderer( - win as BrowserWindow, - HelpActions.CustomerIsSendingToRenderer, - false - ) - }) - - // AUTO DISABLED - fix me if you like :) - // eslint-disable-next-line @typescript-eslint/no-floating-promises - helpWindow.loadURL( - !productionEnvironment - ? `http://localhost:2003/?mode=${Mode.Help}#${URL_MAIN.help}` - : url.format({ - pathname: path.join(__dirname, "index.html"), - protocol: "file:", - slashes: true, - hash: URL_MAIN.help, - search: `?mode=${Mode.Help}`, - }) - ) - registerDownloadHelpHandler() - registerSetHelpStoreHandler() - registerGetHelpStoreHandler() - } else { - helpWindow.show() - } -}) - -ipcMain.answerRenderer( - HelpActions.CustomerIsSendingToMain, - (sending: boolean) => { - ipcMain.callRenderer( - win as BrowserWindow, - HelpActions.CustomerIsSendingToRenderer, - sending - ) - } -) - const createOpenWindowListener = ( channel: string, mode: string, diff --git a/jest.preset.js b/jest.preset.js index 5add69934a..983cc58c6e 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -11,5 +11,7 @@ module.exports = { ...nxPreset.moduleNameMapper, "App/(.*)": `${__dirname}/apps/mudita-center/src/$1`, "Core/(.*)": `${__dirname}/libs/core/$1`, + "p-queue$": `${__dirname}/__mocks__/p-queue.ts`, }, + setupFilesAfterEnv: [`${__dirname}/jest.setup.js`], } diff --git a/jest.setup.js b/jest.setup.js new file mode 100644 index 0000000000..25b5da26e7 --- /dev/null +++ b/jest.setup.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +require("reflect-metadata") diff --git a/jest/jest.config.core.js b/jest/jest.config.core.js index a7527932bc..79988e407d 100644 --- a/jest/jest.config.core.js +++ b/jest/jest.config.core.js @@ -19,6 +19,8 @@ module.exports = { "Core/(.*)": "/libs/core/$1", "Cypress/(.*)": "/apps/mudita-center/cypress/$1", "Storybook/(.*)": "/apps/mudita-center/.storybook/$1", + "p-queue$": `${__dirname}/__mocks__/p-queue.ts`, + "react-markdown": "/jest/testing-support/mocks/react-markdown.tsx", }, rootDir: "../", moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], diff --git a/jest/jest.setup.js b/jest/jest.setup.js index 19b606dd40..7f90b49c62 100644 --- a/jest/jest.setup.js +++ b/jest/jest.setup.js @@ -20,3 +20,5 @@ jest.mock("Core/device/strategies/pure.strategy", () => { expect.extend({ toBeTranslationKey, }) + +jest.mock("@orama/orama") diff --git a/jest/testing-support/mocks/react-markdown.tsx b/jest/testing-support/mocks/react-markdown.tsx new file mode 100644 index 0000000000..e29ae9c0d0 --- /dev/null +++ b/jest/testing-support/mocks/react-markdown.tsx @@ -0,0 +1,7 @@ +import React, { FunctionComponent, PropsWithChildren } from "react" + +const ReactMarkdown: FunctionComponent = ({ children }) => { + return <>{children} +} + +export default ReactMarkdown diff --git a/libs/active-device-registry/feature/.babelrc b/libs/active-device-registry/feature/.babelrc new file mode 100644 index 0000000000..ef4889c1ab --- /dev/null +++ b/libs/active-device-registry/feature/.babelrc @@ -0,0 +1,20 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [ + [ + "styled-components", + { + "pure": true, + "ssr": true + } + ] + ] +} diff --git a/libs/external-tools/matomo-to-gsheet/.eslintrc.json b/libs/active-device-registry/feature/.eslintrc.json similarity index 100% rename from libs/external-tools/matomo-to-gsheet/.eslintrc.json rename to libs/active-device-registry/feature/.eslintrc.json diff --git a/libs/active-device-registry/feature/README.md b/libs/active-device-registry/feature/README.md new file mode 100644 index 0000000000..fa965afb1c --- /dev/null +++ b/libs/active-device-registry/feature/README.md @@ -0,0 +1,7 @@ +# active-device-registry-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test active-device-registry-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/external-tools/matomo-to-gsheet/jest.config.ts b/libs/active-device-registry/feature/jest.config.ts similarity index 69% rename from libs/external-tools/matomo-to-gsheet/jest.config.ts rename to libs/active-device-registry/feature/jest.config.ts index dcbf778f66..8f857c9e58 100644 --- a/libs/external-tools/matomo-to-gsheet/jest.config.ts +++ b/libs/active-device-registry/feature/jest.config.ts @@ -1,11 +1,11 @@ /* eslint-disable */ export default { - displayName: "external-tools-matomo-to-gsheet", + displayName: "active-device-registry-feature", preset: "../../../jest.preset.js", transform: { "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest", "^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }], }, moduleFileExtensions: ["ts", "tsx", "js", "jsx"], - coverageDirectory: "../../../coverage/libs/external-tools/matomo-to-gsheet", + coverageDirectory: "../../../coverage/libs/active-device-registry/feature", } diff --git a/libs/external-tools/matomo-to-gsheet/project.json b/libs/active-device-registry/feature/project.json similarity index 67% rename from libs/external-tools/matomo-to-gsheet/project.json rename to libs/active-device-registry/feature/project.json index 36bbcc6856..0141ee0b5d 100644 --- a/libs/external-tools/matomo-to-gsheet/project.json +++ b/libs/active-device-registry/feature/project.json @@ -1,7 +1,7 @@ { - "name": "external-tools-matomo-to-gsheet", + "name": "active-device-registry-feature", "$schema": "../../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "libs/external-tools/matomo-to-gsheet/src", + "sourceRoot": "libs/active-device-registry/feature/src", "projectType": "library", "tags": [], "targets": { @@ -13,7 +13,7 @@ "executor": "@nx/jest:jest", "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { - "jestConfig": "libs/external-tools/matomo-to-gsheet/jest.config.ts" + "jestConfig": "libs/active-device-registry/feature/jest.config.ts" } } } diff --git a/libs/core/device-manager/controllers/index.ts b/libs/active-device-registry/feature/src/actions/index.ts similarity index 77% rename from libs/core/device-manager/controllers/index.ts rename to libs/active-device-registry/feature/src/actions/index.ts index 086f1e6a9c..676125a458 100644 --- a/libs/core/device-manager/controllers/index.ts +++ b/libs/active-device-registry/feature/src/actions/index.ts @@ -3,4 +3,4 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -export * from "./device-manager.controller" +export * from "./set-active-device.action"; diff --git a/libs/core/device-manager/actions/set-active-device.action.ts b/libs/active-device-registry/feature/src/actions/set-active-device.action.ts similarity index 59% rename from libs/core/device-manager/actions/set-active-device.action.ts rename to libs/active-device-registry/feature/src/actions/set-active-device.action.ts index cd79965753..c784df583e 100644 --- a/libs/core/device-manager/actions/set-active-device.action.ts +++ b/libs/active-device-registry/feature/src/actions/set-active-device.action.ts @@ -4,19 +4,16 @@ */ import { createAsyncThunk } from "@reduxjs/toolkit" +import { setActiveDeviceRequest } from "device-protocol/feature" import { ReduxRootState } from "Core/__deprecated__/renderer/store" -import { DeviceManagerEvent } from "Core/device-manager/constants" -import { setActiveDeviceRequest } from "Core/device-manager/requests" import { DeviceId } from "Core/device/constants/device-id" -import { cleanBackupProcess, cleanRestoreProcess } from "generic-view/store" +import { ActiveDeviceRegistryEvent } from "../constants" export const setActiveDevice = createAsyncThunk< DeviceId | undefined, DeviceId | undefined, { state: ReduxRootState } ->(DeviceManagerEvent.SetActiveDevice, async (payload, { dispatch }) => { +>(ActiveDeviceRegistryEvent.SetActiveDevice, async (payload, { dispatch }) => { await setActiveDeviceRequest(payload) - dispatch(cleanBackupProcess()) - dispatch(cleanRestoreProcess()) return payload }) diff --git a/libs/active-device-registry/feature/src/constants/event.constant.ts b/libs/active-device-registry/feature/src/constants/event.constant.ts new file mode 100644 index 0000000000..5054edbcc1 --- /dev/null +++ b/libs/active-device-registry/feature/src/constants/event.constant.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export enum ActiveDeviceRegistryEvent { + SetActiveDevice = "active-device-registry/set-active-device", +} diff --git a/libs/active-device-registry/feature/src/constants/index.ts b/libs/active-device-registry/feature/src/constants/index.ts new file mode 100644 index 0000000000..fd9c217d57 --- /dev/null +++ b/libs/active-device-registry/feature/src/constants/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./event.constant" diff --git a/libs/active-device-registry/feature/src/index.ts b/libs/active-device-registry/feature/src/index.ts new file mode 100644 index 0000000000..ed357a32d6 --- /dev/null +++ b/libs/active-device-registry/feature/src/index.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./actions" +export * from "./reducers" +export * from "./selectors" diff --git a/libs/active-device-registry/feature/src/reducers/active-device-registry.reducer.ts b/libs/active-device-registry/feature/src/reducers/active-device-registry.reducer.ts new file mode 100644 index 0000000000..83b4c0a07b --- /dev/null +++ b/libs/active-device-registry/feature/src/reducers/active-device-registry.reducer.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createReducer } from "@reduxjs/toolkit" +import { ActiveDeviceRegistryState } from "active-device-registry/models" +import { setActiveDevice } from "../actions" + +export const initialState: ActiveDeviceRegistryState = { + activeDeviceId: undefined, +} + +export const activeDeviceRegistryReducer = createReducer( + initialState, + (builder) => { + builder.addCase(setActiveDevice.fulfilled, (state, action) => { + return { + ...state, + activeDeviceId: action.payload, + } + }) + } +) diff --git a/libs/active-device-registry/feature/src/reducers/index.ts b/libs/active-device-registry/feature/src/reducers/index.ts new file mode 100644 index 0000000000..73250716eb --- /dev/null +++ b/libs/active-device-registry/feature/src/reducers/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./active-device-registry.reducer" diff --git a/libs/core/device-manager/selectors/active-device-id.selector.ts b/libs/active-device-registry/feature/src/selectors/active-device-id.selector.ts similarity index 54% rename from libs/core/device-manager/selectors/active-device-id.selector.ts rename to libs/active-device-registry/feature/src/selectors/active-device-id.selector.ts index 1234c5a626..99d81b4108 100644 --- a/libs/core/device-manager/selectors/active-device-id.selector.ts +++ b/libs/active-device-registry/feature/src/selectors/active-device-id.selector.ts @@ -4,11 +4,11 @@ */ import { createSelector } from "@reduxjs/toolkit" -import { deviceManagerState } from "Core/device-manager/selectors/device-manager-state.selector" +import { activeDeviceRegistryState } from "./active-device-registry-state.selector" export const activeDeviceIdSelector = createSelector( - deviceManagerState, - (deviceManager): string | undefined => { - return deviceManager.activeDeviceId + activeDeviceRegistryState, + (activeDeviceRegistryState): string | undefined => { + return activeDeviceRegistryState.activeDeviceId } ) diff --git a/libs/active-device-registry/feature/src/selectors/active-device-registry-state.selector.ts b/libs/active-device-registry/feature/src/selectors/active-device-registry-state.selector.ts new file mode 100644 index 0000000000..d4f89d7305 --- /dev/null +++ b/libs/active-device-registry/feature/src/selectors/active-device-registry-state.selector.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { ActiveDeviceRegistryState } from "active-device-registry/models" +import { ReduxRootState } from "Core/__deprecated__/renderer/store" + +export const activeDeviceRegistryState = (state: ReduxRootState): ActiveDeviceRegistryState => + state.activeDeviceRegistry diff --git a/libs/active-device-registry/feature/src/selectors/index.ts b/libs/active-device-registry/feature/src/selectors/index.ts new file mode 100644 index 0000000000..927e191c43 --- /dev/null +++ b/libs/active-device-registry/feature/src/selectors/index.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./active-device-id.selector"; +export * from "./active-device-registry-state.selector"; +export * from "./is-active-device-set.selector"; diff --git a/libs/core/device-manager/selectors/is-active-device-set.selector.ts b/libs/active-device-registry/feature/src/selectors/is-active-device-set.selector.ts similarity index 55% rename from libs/core/device-manager/selectors/is-active-device-set.selector.ts rename to libs/active-device-registry/feature/src/selectors/is-active-device-set.selector.ts index 2a4e92c5c3..325207ca8c 100644 --- a/libs/core/device-manager/selectors/is-active-device-set.selector.ts +++ b/libs/active-device-registry/feature/src/selectors/is-active-device-set.selector.ts @@ -4,11 +4,11 @@ */ import { createSelector } from "@reduxjs/toolkit" -import { deviceManagerState } from "Core/device-manager/selectors/device-manager-state.selector" +import { activeDeviceIdSelector } from "./active-device-id.selector" export const isActiveDeviceSet = createSelector( - deviceManagerState, - (deviceManager): boolean => { - return deviceManager.activeDeviceId !== undefined + activeDeviceIdSelector, + (activeDeviceId): boolean => { + return activeDeviceId !== undefined } ) diff --git a/libs/external-tools/matomo-to-gsheet/tsconfig.json b/libs/active-device-registry/feature/tsconfig.json similarity index 100% rename from libs/external-tools/matomo-to-gsheet/tsconfig.json rename to libs/active-device-registry/feature/tsconfig.json diff --git a/libs/external-tools/matomo-to-gsheet/tsconfig.lib.json b/libs/active-device-registry/feature/tsconfig.lib.json similarity index 100% rename from libs/external-tools/matomo-to-gsheet/tsconfig.lib.json rename to libs/active-device-registry/feature/tsconfig.lib.json diff --git a/libs/external-tools/matomo-to-gsheet/tsconfig.spec.json b/libs/active-device-registry/feature/tsconfig.spec.json similarity index 100% rename from libs/external-tools/matomo-to-gsheet/tsconfig.spec.json rename to libs/active-device-registry/feature/tsconfig.spec.json diff --git a/libs/active-device-registry/models/.babelrc b/libs/active-device-registry/models/.babelrc new file mode 100644 index 0000000000..ef4889c1ab --- /dev/null +++ b/libs/active-device-registry/models/.babelrc @@ -0,0 +1,20 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [ + [ + "styled-components", + { + "pure": true, + "ssr": true + } + ] + ] +} diff --git a/libs/active-device-registry/models/.eslintrc.json b/libs/active-device-registry/models/.eslintrc.json new file mode 100644 index 0000000000..cacbe26215 --- /dev/null +++ b/libs/active-device-registry/models/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.js"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/active-device-registry/models/README.md b/libs/active-device-registry/models/README.md new file mode 100644 index 0000000000..e491313413 --- /dev/null +++ b/libs/active-device-registry/models/README.md @@ -0,0 +1,7 @@ +# active-device-registry-models + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test active-device-registry-models` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/active-device-registry/models/jest.config.ts b/libs/active-device-registry/models/jest.config.ts new file mode 100644 index 0000000000..bd4c266fcf --- /dev/null +++ b/libs/active-device-registry/models/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: "active-device-registry-models", + preset: "../../../jest.preset.js", + transform: { + "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest", + "^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }], + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx"], + coverageDirectory: "../../../coverage/libs/active-device-registry/models", +} diff --git a/libs/active-device-registry/models/project.json b/libs/active-device-registry/models/project.json new file mode 100644 index 0000000000..c9ebedf2b2 --- /dev/null +++ b/libs/active-device-registry/models/project.json @@ -0,0 +1,20 @@ +{ + "name": "active-device-registry-models", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/active-device-registry/models/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/active-device-registry/models/jest.config.ts" + } + } + } +} diff --git a/libs/active-device-registry/models/src/active-device-registry.interface.ts b/libs/active-device-registry/models/src/active-device-registry.interface.ts new file mode 100644 index 0000000000..c282c2e45e --- /dev/null +++ b/libs/active-device-registry/models/src/active-device-registry.interface.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { DeviceId } from "Core/device/constants/device-id" + +export interface ActiveDeviceRegistryState { + activeDeviceId: DeviceId | undefined +} diff --git a/libs/active-device-registry/models/src/index.ts b/libs/active-device-registry/models/src/index.ts new file mode 100644 index 0000000000..b761a81f81 --- /dev/null +++ b/libs/active-device-registry/models/src/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./active-device-registry.interface" diff --git a/libs/active-device-registry/models/tsconfig.json b/libs/active-device-registry/models/tsconfig.json new file mode 100644 index 0000000000..4daaf45cd3 --- /dev/null +++ b/libs/active-device-registry/models/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json" +} diff --git a/libs/active-device-registry/models/tsconfig.lib.json b/libs/active-device-registry/models/tsconfig.lib.json new file mode 100644 index 0000000000..21799b3e6b --- /dev/null +++ b/libs/active-device-registry/models/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [ + "node", + + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts" + ] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/active-device-registry/models/tsconfig.spec.json b/libs/active-device-registry/models/tsconfig.spec.json new file mode 100644 index 0000000000..25b7af8f6d --- /dev/null +++ b/libs/active-device-registry/models/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/libs/external-tools/matomo-to-gsheet/.babelrc b/libs/core-device/feature/.babelrc similarity index 100% rename from libs/external-tools/matomo-to-gsheet/.babelrc rename to libs/core-device/feature/.babelrc diff --git a/libs/core-device/feature/.eslintrc.json b/libs/core-device/feature/.eslintrc.json new file mode 100644 index 0000000000..cacbe26215 --- /dev/null +++ b/libs/core-device/feature/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.js"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/core-device/feature/README.md b/libs/core-device/feature/README.md new file mode 100644 index 0000000000..f33c7eb8b8 --- /dev/null +++ b/libs/core-device/feature/README.md @@ -0,0 +1,7 @@ +# core-device-feature + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test core-device-feature` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/core-device/feature/jest.config.ts b/libs/core-device/feature/jest.config.ts new file mode 100644 index 0000000000..9b89b49e49 --- /dev/null +++ b/libs/core-device/feature/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: "core-device-feature", + preset: "../../../jest.preset.js", + transform: { + "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest", + "^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }], + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx"], + coverageDirectory: "../../../coverage/libs/core-device/feature", +} diff --git a/libs/core-device/feature/project.json b/libs/core-device/feature/project.json new file mode 100644 index 0000000000..07471387aa --- /dev/null +++ b/libs/core-device/feature/project.json @@ -0,0 +1,20 @@ +{ + "name": "core-device-feature", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/core-device/feature/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/core-device/feature/jest.config.ts" + } + } + } +} diff --git a/libs/core-device/feature/src/actions/base.action.ts b/libs/core-device/feature/src/actions/base.action.ts new file mode 100644 index 0000000000..219849917b --- /dev/null +++ b/libs/core-device/feature/src/actions/base.action.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createAction } from "@reduxjs/toolkit" +import { DeviceBaseProperties } from "device-protocol/models" +import { DeviceState } from "device-manager/models" +import { CaseColour } from "core-device/models" +import { CoreDeviceEvent } from "../constants" + +export const addDevice = createAction< + DeviceBaseProperties & Partial<{ state: DeviceState; caseColour: CaseColour }> +>(CoreDeviceEvent.AddDevice) + +export const removeDevice = createAction( + CoreDeviceEvent.RemoveDevice +) + +export const setDeviceState = createAction<{ id: string; state: DeviceState }>( + CoreDeviceEvent.SetDeviceState +) diff --git a/libs/core/device-manager/actions/configure-device.action.ts b/libs/core-device/feature/src/actions/configure-device.action.ts similarity index 55% rename from libs/core/device-manager/actions/configure-device.action.ts rename to libs/core-device/feature/src/actions/configure-device.action.ts index 48214e1c75..f1c541fa51 100644 --- a/libs/core/device-manager/actions/configure-device.action.ts +++ b/libs/core-device/feature/src/actions/configure-device.action.ts @@ -5,11 +5,10 @@ import { createAsyncThunk } from "@reduxjs/toolkit" import { ReduxRootState } from "Core/__deprecated__/renderer/store" -import { DeviceManagerEvent } from "Core/device-manager/constants" import { DeviceId } from "Core/device/constants/device-id" -import { getDeviceConfigurationRequest } from "Core/device-manager/requests/get-device-configuration.request" -import { DeviceConfiguration } from "Core/device-manager/controllers" -import { DeviceType } from "Core/device" +import { getDeviceConfigurationRequest } from "../requests" +import { DeviceConfiguration } from "../controllers" +import { CoreDeviceEvent } from "../constants" interface ConfigureDevicePayload extends Partial { id: DeviceId @@ -19,13 +18,7 @@ export const configureDevice = createAsyncThunk< ConfigureDevicePayload, DeviceId, { state: ReduxRootState } ->(DeviceManagerEvent.ConfigureDevice, async (id, {getState}) => { - // TODO: tmp solution to handle APIDevice - const device = getState().deviceManager.devices.find((device) => device.id === id) - if(device?.deviceType === DeviceType.APIDevice){ - return { id } - } - +>(CoreDeviceEvent.ConfigureDevice, async (id) => { const result = await getDeviceConfigurationRequest(id) if (result.ok) { diff --git a/libs/core-device/feature/src/actions/index.ts b/libs/core-device/feature/src/actions/index.ts new file mode 100644 index 0000000000..9c5a7b6378 --- /dev/null +++ b/libs/core-device/feature/src/actions/index.ts @@ -0,0 +1,7 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./base.action" +export * from "./configure-device.action" diff --git a/libs/core-device/feature/src/constants/controller.constant.ts b/libs/core-device/feature/src/constants/controller.constant.ts new file mode 100644 index 0000000000..5b127b3fca --- /dev/null +++ b/libs/core-device/feature/src/constants/controller.constant.ts @@ -0,0 +1,8 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export enum IpcCoreDeviceEvent { + GetCoreDeviceConfiguration = "core-device_get-core-device-configuration", +} diff --git a/libs/core-device/feature/src/constants/event.constant.ts b/libs/core-device/feature/src/constants/event.constant.ts new file mode 100644 index 0000000000..1a4e71fb22 --- /dev/null +++ b/libs/core-device/feature/src/constants/event.constant.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export enum CoreDeviceEvent { + AddDevice = "core-device_add-device", + RemoveDevice = "core-device_remove-device", + SetDeviceState = "core-device_set-device-state", + ConfigureDevice = "core-device_configure-device", +} diff --git a/libs/core/device-manager/constants/index.ts b/libs/core-device/feature/src/constants/index.ts similarity index 87% rename from libs/core/device-manager/constants/index.ts rename to libs/core-device/feature/src/constants/index.ts index 47cd8ebe91..5a48343da1 100644 --- a/libs/core/device-manager/constants/index.ts +++ b/libs/core-device/feature/src/constants/index.ts @@ -4,5 +4,4 @@ */ export * from "./controller.constant" -export * from "./error.constant" export * from "./event.constant" diff --git a/libs/core/device-manager/controllers/device-manager.controller.ts b/libs/core-device/feature/src/controllers/core-device.controller.ts similarity index 64% rename from libs/core/device-manager/controllers/device-manager.controller.ts rename to libs/core-device/feature/src/controllers/core-device.controller.ts index 494aa405a9..6debfbceb2 100644 --- a/libs/core/device-manager/controllers/device-manager.controller.ts +++ b/libs/core-device/feature/src/controllers/core-device.controller.ts @@ -4,36 +4,31 @@ */ import { IpcEvent } from "Core/core/decorators" -import { DeviceManager } from "Core/device-manager/services" -import { IpcDeviceManagerEvent } from "Core/device-manager/constants" +import { DeviceProtocol } from "device-protocol/feature" import { Result, ResultObject } from "Core/core/builder" import { DeviceId } from "Core/device/constants/device-id" +import { DeviceInfo } from "Core/device/types/mudita-os" import { CaseColour, DeviceCommunicationError, Endpoint, Method, -} from "Core/device" -import { DeviceInfo } from "Core/device/types/mudita-os" -import { DeviceCacheConfigurationService } from "Core/device-manager/services/device-cache-configuration.service" +} from "core-device/models" +import { DeviceCacheConfigurationService } from "../services" +import { IpcCoreDeviceEvent } from "../constants" export interface DeviceConfiguration { caseColour: CaseColour | undefined serialNumber: string | undefined } -export class DeviceManagerController { +export class CoreDeviceController { constructor( - private deviceManager: DeviceManager, + private deviceProtocol: DeviceProtocol, private deviceCacheConfigurationService: DeviceCacheConfigurationService ) {} - @IpcEvent(IpcDeviceManagerEvent.SetActiveDevice) - public setActiveDevice(id: DeviceId | undefined): ResultObject { - return this.deviceManager.setActiveDevice(id) - } - - @IpcEvent(IpcDeviceManagerEvent.GetDeviceConfiguration) + @IpcEvent(IpcCoreDeviceEvent.GetCoreDeviceConfiguration) public async request( id: DeviceId ): Promise> { @@ -43,7 +38,7 @@ export class DeviceManagerController { return Result.success(deviceConfigurationCached) } - const result = await this.deviceManager.request(id, { + const result = await this.deviceProtocol.request(id, { endpoint: Endpoint.DeviceInfo, method: Method.Get, options: { @@ -65,9 +60,4 @@ export class DeviceManagerController { return result } } - - @IpcEvent(IpcDeviceManagerEvent.ConnectDevice) - public connectDevice(id: DeviceId): Promise> { - return this.deviceManager.connectDevice(id) - } } diff --git a/libs/core-device/feature/src/controllers/index.ts b/libs/core-device/feature/src/controllers/index.ts new file mode 100644 index 0000000000..529b494a9b --- /dev/null +++ b/libs/core-device/feature/src/controllers/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./core-device.controller" diff --git a/libs/core-device/feature/src/core-device.module.ts b/libs/core-device/feature/src/core-device.module.ts new file mode 100644 index 0000000000..69cad99ca6 --- /dev/null +++ b/libs/core-device/feature/src/core-device.module.ts @@ -0,0 +1,25 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { DeviceProtocol } from "device-protocol/feature" +import { FileSystemService } from "Core/file-system/services/file-system.service.refactored" +import { DeviceCacheConfigurationService } from "./services" +import { CoreDeviceController } from "./controllers" + +export class CoreDeviceModule { + public controllers + + constructor( + public deviceProtocol: DeviceProtocol, + public fileSystem: FileSystemService + ) { + const deviceManagerController = new CoreDeviceController( + this.deviceProtocol, + new DeviceCacheConfigurationService(this.fileSystem) + ) + + this.controllers = [deviceManagerController] + } +} diff --git a/libs/core-device/feature/src/hooks/index.ts b/libs/core-device/feature/src/hooks/index.ts new file mode 100644 index 0000000000..e975497e8b --- /dev/null +++ b/libs/core-device/feature/src/hooks/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./use-core-device-protocol-listeners" diff --git a/libs/core-device/feature/src/hooks/use-core-device-protocol-listeners.ts b/libs/core-device/feature/src/hooks/use-core-device-protocol-listeners.ts new file mode 100644 index 0000000000..116ab2920b --- /dev/null +++ b/libs/core-device/feature/src/hooks/use-core-device-protocol-listeners.ts @@ -0,0 +1,77 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { useCallback, useEffect } from "react" +import { useDispatch } from "react-redux" +import { answerMain, useDebouncedEventsHandler } from "shared/utils" +import { DeviceState } from "device-manager/models" +import { DeviceProtocolMainEvent, DeviceType, DeviceBaseProperties } from "device-protocol/models" +import { Dispatch } from "Core/__deprecated__/renderer/store" +import { addDevice, configureDevice, removeDevice } from "../actions" +import { getDeviceConfigurationRequest } from "../requests" + +export const useCoreDeviceProtocolListeners = () => { + const dispatch = useDispatch() + const handleDevicesDetached = useHandleDevicesDetached() + const batchDeviceDetachedEvents = + useDebouncedEventsHandler(handleDevicesDetached) + + useEffect(() => { + return answerMain( + DeviceProtocolMainEvent.DeviceConnected, + (properties) => { + const { deviceType } = properties + if (deviceType === DeviceType.APIDevice) { + return + } + + dispatch(addDevice(properties)) + dispatch(configureDevice(properties.id)) + } + ) + }, [dispatch]) + + useEffect(() => { + return answerMain( + DeviceProtocolMainEvent.DeviceConnectFailed, + async (properties) => { + const { deviceType } = properties + if (deviceType === DeviceType.APIDevice) { + return + } + + const result = await getDeviceConfigurationRequest(properties.id) + const caseColour = result.ok ? result.data.caseColour : undefined + + dispatch( + addDevice({ ...properties, caseColour, state: DeviceState.Failed }) + ) + } + ) + }, [dispatch]) + + useEffect(() => { + return answerMain( + DeviceProtocolMainEvent.DeviceDetached, + batchDeviceDetachedEvents + ) + }, [dispatch, batchDeviceDetachedEvents]) +} + +const useHandleDevicesDetached = () => { + const dispatch = useDispatch() + + return useCallback( + async (deviceDetachedEvents: DeviceBaseProperties[]) => { + for (const event of deviceDetachedEvents) { + const { deviceType } = event + if (deviceType !== DeviceType.APIDevice) { + dispatch(removeDevice(event)) + } + } + }, + [dispatch] + ) +} diff --git a/libs/core-device/feature/src/index.ts b/libs/core-device/feature/src/index.ts new file mode 100644 index 0000000000..80b5e6ceb5 --- /dev/null +++ b/libs/core-device/feature/src/index.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./actions" +export * from "./hooks" +export * from "./reducers" +export * from "./requests" +export * from "./selectors" +export * from "./core-device.module" diff --git a/libs/core-device/feature/src/reducers/core-device.reducer.ts b/libs/core-device/feature/src/reducers/core-device.reducer.ts new file mode 100644 index 0000000000..9509429b81 --- /dev/null +++ b/libs/core-device/feature/src/reducers/core-device.reducer.ts @@ -0,0 +1,56 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createReducer } from "@reduxjs/toolkit" +import { DeviceState } from "device-manager/models" +import { CoreDeviceState } from "core-device/models" +import { + addDevice, + removeDevice, + configureDevice, + setDeviceState, +} from "../actions" + +export const initialState: CoreDeviceState = { + devices: {}, +} + +export const coreDeviceReducer = createReducer( + initialState, + (builder) => { + builder + .addCase(addDevice, (state, action) => { + state.devices[action.payload.id] = { + caseColour: undefined, + state: DeviceState.Connected, + ...action.payload, + } + }) + .addCase(removeDevice, (state, action) => { + delete state.devices[action.payload.id] + }) + .addCase(configureDevice.fulfilled, (state, action) => { + const id = action.payload.id + const device = state.devices[id] + state.devices[id] = { + ...device, + caseColour: action.payload.caseColour ?? device.caseColour, + serialNumber: action.payload.serialNumber ?? device.serialNumber, + state: DeviceState.Configured, + } + }) + .addCase(setDeviceState, (state, action) => { + if (action.payload) { + const id = action.payload.id + const device = state.devices[id] + const deviceState = action.payload.state + state.devices[id] = { + ...device, + state: deviceState, + } + } + }) + } +) diff --git a/libs/core-device/feature/src/reducers/index.ts b/libs/core-device/feature/src/reducers/index.ts new file mode 100644 index 0000000000..47fd2cfa48 --- /dev/null +++ b/libs/core-device/feature/src/reducers/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./core-device.reducer" diff --git a/libs/core/device-manager/requests/get-device-configuration.request.ts b/libs/core-device/feature/src/requests/get-device-configuration.request.ts similarity index 66% rename from libs/core/device-manager/requests/get-device-configuration.request.ts rename to libs/core-device/feature/src/requests/get-device-configuration.request.ts index 33ae4b1987..7e46733c8e 100644 --- a/libs/core/device-manager/requests/get-device-configuration.request.ts +++ b/libs/core-device/feature/src/requests/get-device-configuration.request.ts @@ -5,12 +5,12 @@ import { ipcRenderer } from "electron-better-ipc" import { ResultObject } from "Core/core/builder" -import { IpcDeviceManagerEvent } from "Core/device-manager/constants" import { DeviceId } from "Core/device/constants/device-id" -import { DeviceConfiguration } from "Core/device-manager/controllers" +import { DeviceConfiguration } from "../controllers" +import { IpcCoreDeviceEvent } from "../constants" export const getDeviceConfigurationRequest = async ( id: DeviceId ): Promise> => { - return ipcRenderer.callMain(IpcDeviceManagerEvent.GetDeviceConfiguration, id) + return ipcRenderer.callMain(IpcCoreDeviceEvent.GetCoreDeviceConfiguration, id) } diff --git a/libs/core-device/feature/src/requests/index.ts b/libs/core-device/feature/src/requests/index.ts new file mode 100644 index 0000000000..b1eb40f23f --- /dev/null +++ b/libs/core-device/feature/src/requests/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./get-device-configuration.request" diff --git a/libs/core-device/feature/src/selectors/core-device-state.selector.ts b/libs/core-device/feature/src/selectors/core-device-state.selector.ts new file mode 100644 index 0000000000..1f467f5814 --- /dev/null +++ b/libs/core-device/feature/src/selectors/core-device-state.selector.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { ReduxRootState } from "Core/__deprecated__/renderer/store" +import { CoreDeviceState } from "core-device/models" + +export const coreDeviceState = (state: ReduxRootState): CoreDeviceState => + state.coreDevice diff --git a/libs/core-device/feature/src/selectors/get-configured-core-devices.selector.ts b/libs/core-device/feature/src/selectors/get-configured-core-devices.selector.ts new file mode 100644 index 0000000000..d1fbffa9c7 --- /dev/null +++ b/libs/core-device/feature/src/selectors/get-configured-core-devices.selector.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createSelector } from "@reduxjs/toolkit" +import { Device } from "core-device/models" +import { DeviceState } from "device-manager/models" +import { getCoreDevicesSelector } from "./get-core-devices.selector" + +export const getConfiguredCoreDevicesSelector = createSelector( + getCoreDevicesSelector, + (devices): Device[] => { + return devices.filter(({ state }) => state === DeviceState.Configured) + } +) diff --git a/libs/core-device/feature/src/selectors/get-core-devices.selector.ts b/libs/core-device/feature/src/selectors/get-core-devices.selector.ts new file mode 100644 index 0000000000..b3f26913ce --- /dev/null +++ b/libs/core-device/feature/src/selectors/get-core-devices.selector.ts @@ -0,0 +1,15 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createSelector } from "@reduxjs/toolkit" +import { Device } from "core-device/models" +import { coreDeviceState } from "./core-device-state.selector" + +export const getCoreDevicesSelector = createSelector( + coreDeviceState, + ({ devices }): Device[] => { + return Object.values(devices); + } +) diff --git a/libs/core-device/feature/src/selectors/get-failed-core-devices.selector.ts b/libs/core-device/feature/src/selectors/get-failed-core-devices.selector.ts new file mode 100644 index 0000000000..8230b8d17c --- /dev/null +++ b/libs/core-device/feature/src/selectors/get-failed-core-devices.selector.ts @@ -0,0 +1,16 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { createSelector } from "@reduxjs/toolkit" +import { Device } from "core-device/models" +import { DeviceState } from "device-manager/models" +import { getCoreDevicesSelector } from "./get-core-devices.selector" + +export const getFailedCoreDevicesSelector = createSelector( + getCoreDevicesSelector, + (devices): Device[] => { + return devices.filter(({ state }) => state === DeviceState.Failed) + } +) diff --git a/libs/core-device/feature/src/selectors/index.ts b/libs/core-device/feature/src/selectors/index.ts new file mode 100644 index 0000000000..63a3ecd917 --- /dev/null +++ b/libs/core-device/feature/src/selectors/index.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./core-device-state.selector" +export * from "./get-configured-core-devices.selector" +export * from "./get-core-devices.selector" +export * from "./get-failed-core-devices.selector" diff --git a/libs/core/device-manager/services/device-cache-configuration.service.ts b/libs/core-device/feature/src/services/device-cache-configuration.service.ts similarity index 95% rename from libs/core/device-manager/services/device-cache-configuration.service.ts rename to libs/core-device/feature/src/services/device-cache-configuration.service.ts index 3f874ba15c..3c826ee59d 100644 --- a/libs/core/device-manager/services/device-cache-configuration.service.ts +++ b/libs/core-device/feature/src/services/device-cache-configuration.service.ts @@ -6,8 +6,8 @@ import path from "path" import { FileSystemService } from "Core/file-system/services/file-system.service.refactored" import getAppPath from "Core/__deprecated__/main/utils/get-app-path" -import { DeviceConfiguration } from "Core/device-manager/controllers" import { DeviceId } from "Core/device/constants/device-id" +import { DeviceConfiguration } from "../controllers" type CacheMap = Record diff --git a/libs/core-device/feature/src/services/index.ts b/libs/core-device/feature/src/services/index.ts new file mode 100644 index 0000000000..6d80584128 --- /dev/null +++ b/libs/core-device/feature/src/services/index.ts @@ -0,0 +1,6 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./device-cache-configuration.service" diff --git a/libs/core-device/feature/tsconfig.json b/libs/core-device/feature/tsconfig.json new file mode 100644 index 0000000000..4daaf45cd3 --- /dev/null +++ b/libs/core-device/feature/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json" +} diff --git a/libs/core-device/feature/tsconfig.lib.json b/libs/core-device/feature/tsconfig.lib.json new file mode 100644 index 0000000000..21799b3e6b --- /dev/null +++ b/libs/core-device/feature/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [ + "node", + + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts" + ] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/core-device/feature/tsconfig.spec.json b/libs/core-device/feature/tsconfig.spec.json new file mode 100644 index 0000000000..25b7af8f6d --- /dev/null +++ b/libs/core-device/feature/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/libs/core-device/models/.babelrc b/libs/core-device/models/.babelrc new file mode 100644 index 0000000000..ef4889c1ab --- /dev/null +++ b/libs/core-device/models/.babelrc @@ -0,0 +1,20 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [ + [ + "styled-components", + { + "pure": true, + "ssr": true + } + ] + ] +} diff --git a/libs/core-device/models/.eslintrc.json b/libs/core-device/models/.eslintrc.json new file mode 100644 index 0000000000..cacbe26215 --- /dev/null +++ b/libs/core-device/models/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.js"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/core-device/models/README.md b/libs/core-device/models/README.md new file mode 100644 index 0000000000..7e82719bfe --- /dev/null +++ b/libs/core-device/models/README.md @@ -0,0 +1,7 @@ +# core-device-models + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test core-device-models` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/core-device/models/jest.config.ts b/libs/core-device/models/jest.config.ts new file mode 100644 index 0000000000..12d1051c4d --- /dev/null +++ b/libs/core-device/models/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: "core-device-models", + preset: "../../../jest.preset.js", + transform: { + "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nx/react/plugins/jest", + "^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nx/react/babel"] }], + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx"], + coverageDirectory: "../../../coverage/libs/core-device/models", +} diff --git a/libs/core-device/models/project.json b/libs/core-device/models/project.json new file mode 100644 index 0000000000..95e0a8f8b0 --- /dev/null +++ b/libs/core-device/models/project.json @@ -0,0 +1,20 @@ +{ + "name": "core-device-models", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/core-device/models/src", + "projectType": "library", + "tags": [], + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/core-device/models/jest.config.ts" + } + } + } +} diff --git a/libs/core/device/constants/case-colour.constant.ts b/libs/core-device/models/src/case-colour.constant.ts similarity index 100% rename from libs/core/device/constants/case-colour.constant.ts rename to libs/core-device/models/src/case-colour.constant.ts diff --git a/libs/core-device/models/src/core-device.interface.ts b/libs/core-device/models/src/core-device.interface.ts new file mode 100644 index 0000000000..9155e9d903 --- /dev/null +++ b/libs/core-device/models/src/core-device.interface.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import { CaseColour } from "core-device/models" +import { DeviceType } from "device-protocol/models" +import { DeviceProperties } from "device-manager/models" +import { DeviceId } from "Core/device/constants/device-id" + +export interface Device extends DeviceProperties { + id: DeviceId + serialNumber: string | undefined + deviceType: DeviceType + caseColour: CaseColour | undefined +} + +export interface CoreDeviceState { + devices: Record +} diff --git a/libs/core/device/constants/device-communication-error.constant.ts b/libs/core-device/models/src/device-communication-error.constant.ts similarity index 100% rename from libs/core/device/constants/device-communication-error.constant.ts rename to libs/core-device/models/src/device-communication-error.constant.ts diff --git a/libs/core/device/constants/endpoint.constant.ts b/libs/core-device/models/src/endpoint.constant.ts similarity index 100% rename from libs/core/device/constants/endpoint.constant.ts rename to libs/core-device/models/src/endpoint.constant.ts diff --git a/libs/core-device/models/src/index.ts b/libs/core-device/models/src/index.ts new file mode 100644 index 0000000000..a2bc29af27 --- /dev/null +++ b/libs/core-device/models/src/index.ts @@ -0,0 +1,10 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +export * from "./case-colour.constant" +export * from "./core-device.interface" +export * from "./device-communication-error.constant" +export * from "./endpoint.constant" +export * from "./request-method.constant" diff --git a/libs/core/device/constants/request-method.constant.ts b/libs/core-device/models/src/request-method.constant.ts similarity index 100% rename from libs/core/device/constants/request-method.constant.ts rename to libs/core-device/models/src/request-method.constant.ts diff --git a/libs/core-device/models/tsconfig.json b/libs/core-device/models/tsconfig.json new file mode 100644 index 0000000000..4daaf45cd3 --- /dev/null +++ b/libs/core-device/models/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strict": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json" +} diff --git a/libs/core-device/models/tsconfig.lib.json b/libs/core-device/models/tsconfig.lib.json new file mode 100644 index 0000000000..21799b3e6b --- /dev/null +++ b/libs/core-device/models/tsconfig.lib.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "types": [ + "node", + + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts" + ] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/core-device/models/tsconfig.spec.json b/libs/core-device/models/tsconfig.spec.json new file mode 100644 index 0000000000..25b7af8f6d --- /dev/null +++ b/libs/core-device/models/tsconfig.spec.json @@ -0,0 +1,20 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/libs/core/__deprecated__/api/mudita-center-server/client.interface.ts b/libs/core/__deprecated__/api/mudita-center-server/client.interface.ts index a43730d82a..50eb56cf3c 100644 --- a/libs/core/__deprecated__/api/mudita-center-server/client.interface.ts +++ b/libs/core/__deprecated__/api/mudita-center-server/client.interface.ts @@ -3,15 +3,9 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { EntryCollection, SyncCollection } from "contentful" +import { EntryCollection } from "contentful" import { NewsEntry } from "Core/news/dto" export interface ClientInterface { getNews(query: { limit: number }): Promise> - getHelp(query: HelpQuery): Promise -} - -export interface HelpQuery { - nextSyncToken?: string - locale?: string } diff --git a/libs/core/__deprecated__/api/mudita-center-server/client.test.ts b/libs/core/__deprecated__/api/mudita-center-server/client.test.ts index 47c07dc743..159db05f9b 100644 --- a/libs/core/__deprecated__/api/mudita-center-server/client.test.ts +++ b/libs/core/__deprecated__/api/mudita-center-server/client.test.ts @@ -36,24 +36,3 @@ test("returns news response properly", async () => { const result = await client.getNews({ limit: 3 }) expect(result).toStrictEqual({ data: { response: "ok" } }) }) - -test("returns help response properly", async () => { - const data = { - response: "ok", - } - axiosMock.onGet(MuditaCenterServerRoutes.Help).replyOnce(200, { - data, - }) - const client = new Client() - const result = await client.getHelp({ - nextSyncToken: "dsad921342", - }) - expect(result).toStrictEqual({ data }) -}) - -test("returns 404 when no query is provided", () => { - const client = new Client() - void expect(async () => { - await client.getHelp({}) - }).rejects.toThrowError(`Error: Request failed with status code 404`) -}) diff --git a/libs/core/__deprecated__/api/mudita-center-server/client.ts b/libs/core/__deprecated__/api/mudita-center-server/client.ts index c373fbc2f9..df203d000d 100644 --- a/libs/core/__deprecated__/api/mudita-center-server/client.ts +++ b/libs/core/__deprecated__/api/mudita-center-server/client.ts @@ -6,14 +6,11 @@ import { NewsEntry } from "Core/news/dto" import { OsEnvironment } from "Core/update/constants" import { ReleaseManifest } from "Core/update/dto" -import { - ClientInterface, - HelpQuery, -} from "Core/__deprecated__/api/mudita-center-server/client.interface" +import { ClientInterface } from "Core/__deprecated__/api/mudita-center-server/client.interface" import { MuditaCenterServerRoutes } from "Core/__deprecated__/api/mudita-center-server/mudita-center-server-routes" import { Product } from "Core/__deprecated__/main/constants" import axios, { AxiosInstance, AxiosResponse } from "axios" -import { EntryCollection, SyncCollection } from "contentful" +import { EntryCollection } from "contentful" import https from "https" export interface getLatestProductionReleaseParams { @@ -65,33 +62,6 @@ export class Client implements ClientInterface { } } - async getHelp(query: HelpQuery): Promise { - try { - const params = new URLSearchParams({ - locale: query.locale as string, - }) - - if (query.nextSyncToken) { - params.append("nextSyncToken", query.nextSyncToken) - } - - // AUTO DISABLED - fix me if you like :) - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const { data }: AxiosResponse = await this.httpClient.get( - MuditaCenterServerRoutes.Help, - { params } - ) - - // AUTO DISABLED - fix me if you like :) - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return data - // AUTO DISABLED - fix me if you like :) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (error: any) { - throw new Error(error) - } - } - async getExternalUsageDevice(serialNumber: string): Promise { try { const params: ExternalUsageDeviceQueryParams = { diff --git a/libs/core/__deprecated__/api/mudita-center-server/mudita-center-server-routes.ts b/libs/core/__deprecated__/api/mudita-center-server/mudita-center-server-routes.ts index d12707a390..7e7aa5189a 100644 --- a/libs/core/__deprecated__/api/mudita-center-server/mudita-center-server-routes.ts +++ b/libs/core/__deprecated__/api/mudita-center-server/mudita-center-server-routes.ts @@ -5,7 +5,6 @@ export enum MuditaCenterServerRoutes { News = "news", - Help = "help", GetReleaseV2 = "v2-get-release", AppConfigurationV2 = "v2-app-configuration", ExternalUsageDevice = "external-usage-device", diff --git a/libs/core/__deprecated__/common/enums/help-actions.enum.ts b/libs/core/__deprecated__/common/enums/help-actions.enum.ts index 16c6ef5c75..306b956264 100644 --- a/libs/core/__deprecated__/common/enums/help-actions.enum.ts +++ b/libs/core/__deprecated__/common/enums/help-actions.enum.ts @@ -4,10 +4,6 @@ */ export enum HelpActions { - OpenWindow = "open-window", - SetStoreValue = "set-store-value", - GetStore = "get-store", - DownloadContentfulData = "download-contentful-data", CustomerIsSendingToMain = "customer-is-sending-to-main", CustomerIsSendingToRenderer = "customer-is-sending-to-renderer", } diff --git a/libs/core/__deprecated__/common/interfaces/device-info.interface.ts b/libs/core/__deprecated__/common/interfaces/device-info.interface.ts index 5c9d0a1b67..c751d83be0 100644 --- a/libs/core/__deprecated__/common/interfaces/device-info.interface.ts +++ b/libs/core/__deprecated__/common/interfaces/device-info.interface.ts @@ -3,7 +3,7 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { CaseColour } from "Core/device/constants" +import { CaseColour } from "core-device/models" export default interface DeviceInfo { readonly serialNumber: string diff --git a/libs/core/__deprecated__/main/functions/download-help-handler.ts b/libs/core/__deprecated__/main/functions/download-help-handler.ts deleted file mode 100644 index c2d7794b85..0000000000 --- a/libs/core/__deprecated__/main/functions/download-help-handler.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) Mudita sp. z o.o. All rights reserved. - * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md - */ - -import { ipcMain } from "electron-better-ipc" -import { HelpActions } from "Core/__deprecated__/common/enums/help-actions.enum" -import { settingsStore } from "Core/settings/store" -import { normalizeHelpData } from "Core/__deprecated__/renderer/utils/contentful/normalize-help-data" -import { createClient } from "Core/__deprecated__/api/mudita-center-server" -import logger from "Core/__deprecated__/main/utils/logger" -import { HelpQuery } from "Core/__deprecated__/api/mudita-center-server/client.interface" - -// AUTO DISABLED - fix me if you like :) -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const registerDownloadHelpHandler = () => { - const locale = settingsStore.get("language") - - ipcMain.answerRenderer(HelpActions.DownloadContentfulData, async () => { - const client = createClient() - const helpQuery: HelpQuery = { - locale, - } - try { - return normalizeHelpData(await client.getHelp(helpQuery), locale) - } catch (error) { - logger.error( - `Help: loads data from from mudita-center-server fails. Data: ${JSON.stringify( - error - )}` - ) - return false - } - }) -} - -// AUTO DISABLED - fix me if you like :) -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const removeDownloadHelpHandler = () => - ipcMain.removeHandler(HelpActions.DownloadContentfulData) diff --git a/libs/core/__deprecated__/main/functions/get-help-store-handler.ts b/libs/core/__deprecated__/main/functions/get-help-store-handler.ts deleted file mode 100644 index 7fc4e2ded4..0000000000 --- a/libs/core/__deprecated__/main/functions/get-help-store-handler.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) Mudita sp. z o.o. All rights reserved. - * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md - */ - -import { ipcMain } from "electron-better-ipc" -import { HelpActions } from "Core/__deprecated__/common/enums/help-actions.enum" -import helpStore from "Core/__deprecated__/main/store/help" - -// AUTO DISABLED - fix me if you like :) -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const registerGetHelpStoreHandler = () => - ipcMain.answerRenderer(HelpActions.GetStore, () => { - return helpStore.get("data") - }) - -// AUTO DISABLED - fix me if you like :) -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const removeGetHelpStoreHandler = () => - ipcMain.removeHandler(HelpActions.GetStore) diff --git a/libs/core/__deprecated__/main/functions/set-help-store-handler.ts b/libs/core/__deprecated__/main/functions/set-help-store-handler.ts deleted file mode 100644 index f30c5e4f9c..0000000000 --- a/libs/core/__deprecated__/main/functions/set-help-store-handler.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) Mudita sp. z o.o. All rights reserved. - * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md - */ - -import { ipcMain } from "electron-better-ipc" -import { HelpActions } from "Core/__deprecated__/common/enums/help-actions.enum" -import helpStore from "Core/__deprecated__/main/store/help" - -export const registerSetHelpStoreHandler = (): (() => void) => - ipcMain.answerRenderer(HelpActions.SetStoreValue, (response) => { - return helpStore.set("data", response) - }) - -// AUTO DISABLED - fix me if you like :) -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export const removeSetHelpStoreHandler = () => - ipcMain.removeHandler(HelpActions.SetStoreValue) diff --git a/libs/core/__deprecated__/renderer/components/core/badge/badge-with-icon.component.tsx b/libs/core/__deprecated__/renderer/components/core/badge/badge-with-icon.component.tsx new file mode 100644 index 0000000000..dd54a37498 --- /dev/null +++ b/libs/core/__deprecated__/renderer/components/core/badge/badge-with-icon.component.tsx @@ -0,0 +1,21 @@ +/** + * Copyright (c) Mudita sp. z o.o. All rights reserved. + * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md + */ + +import styled from "styled-components" + +export const BadgeWithIcon = styled.div` + display: flex; + justify-content: center; + align-items: center; + gap: 0.8rem; + position: absolute; + right: 0; + top: 0; + background-color: black; + border-radius: 0.4rem; + padding: 0 1rem 0 0.8rem; + line-height: 2rem; + font-weight: 700; +` diff --git a/libs/core/__deprecated__/renderer/components/core/button/button.component.tsx b/libs/core/__deprecated__/renderer/components/core/button/button.component.tsx index de3992f065..25ac0ddb53 100755 --- a/libs/core/__deprecated__/renderer/components/core/button/button.component.tsx +++ b/libs/core/__deprecated__/renderer/components/core/button/button.component.tsx @@ -27,6 +27,7 @@ import { IconBadgeType } from "Core/__deprecated__/renderer/components/core/icon export interface ButtonComponentProps { nav?: boolean exact?: boolean + disableWhenActive?: boolean disabled?: boolean displayStyle?: DisplayStyle href?: string @@ -55,6 +56,7 @@ const ButtonComponent: FunctionComponent = ({ disabled = false, displayStyle = DisplayStyle.Primary, exact, + disableWhenActive = true, href, Icon, iconSize = IconSize.Big, @@ -86,6 +88,7 @@ const ButtonComponent: FunctionComponent = ({ Object.assign(filteredProps, { to, exact, + disableWhenActive, activeClassName, }) } else if (to) { diff --git a/libs/core/__deprecated__/renderer/components/core/button/button.stories.tsx b/libs/core/__deprecated__/renderer/components/core/button/button.stories.tsx index ec10319ab7..0931c37307 100755 --- a/libs/core/__deprecated__/renderer/components/core/button/button.stories.tsx +++ b/libs/core/__deprecated__/renderer/components/core/button/button.stories.tsx @@ -181,7 +181,7 @@ storiesOf("Components|Core/Button", module) displayStyle={DisplayStyle.MenuLink} label="I open Google in new tab" href="http://www.google.pl" - iconSize={IconSize.Bigger} + iconSize={IconSize.Large} /> @@ -192,7 +192,7 @@ storiesOf("Components|Core/Button", module) displayStyle={DisplayStyle.MenuLink} label="I open Google in new tab" href="http://www.google.pl" - iconSize={IconSize.Bigger} + iconSize={IconSize.Large} /> diff --git a/libs/core/__deprecated__/renderer/components/core/button/button.styled.elements.tsx b/libs/core/__deprecated__/renderer/components/core/button/button.styled.elements.tsx index fd2c62c998..a74511dee4 100644 --- a/libs/core/__deprecated__/renderer/components/core/button/button.styled.elements.tsx +++ b/libs/core/__deprecated__/renderer/components/core/button/button.styled.elements.tsx @@ -368,12 +368,14 @@ const buttonStyles = css<{ export const StyledNavLink = styled(NavLink)<{ displayStyle: DisplayStyle disabled: boolean + disableWhenActive: boolean size: Size }>` ${buttonStyles} &.${activeClassName} { - pointer-events: none; + pointer-events: ${({ disableWhenActive }) => + disableWhenActive ? "none" : "all"}; } ` diff --git a/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.component.tsx b/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.component.tsx index 9993c90d72..42b26931aa 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.component.tsx +++ b/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.component.tsx @@ -3,13 +3,13 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { FunctionComponent } from "Core/core/types/function-component.interface" import * as React from "react" +import { DeviceType } from "device-protocol/models" +import { FunctionComponent } from "Core/core/types/function-component.interface" import Icon, { Props as IconProps, } from "Core/__deprecated__/renderer/components/core/icon/icon.component" import { IconType } from "Core/__deprecated__/renderer/components/core/icon/icon-type" -import { DeviceType } from "Core/device" export interface BatteryIconProps { level: number diff --git a/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.test.tsx b/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.test.tsx index 09a613f8fc..b5964f7cb9 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.test.tsx +++ b/libs/core/__deprecated__/renderer/components/core/icon/battery-icon.test.tsx @@ -4,9 +4,9 @@ */ import React from "react" +import { DeviceType } from "device-protocol/models" import { renderWithThemeAndIntl } from "Core/__deprecated__/renderer/utils/render-with-theme-and-intl" import BatteryIcon from "Core/__deprecated__/renderer/components/core/icon/battery-icon.component" -import { DeviceType } from "Core/device" describe("battery icon returns correct component", () => { const testScenario = [ diff --git a/libs/core/__deprecated__/renderer/components/core/icon/icon-type.ts b/libs/core/__deprecated__/renderer/components/core/icon/icon-type.ts index bb0805c0fc..0ff97b9c54 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/icon-type.ts +++ b/libs/core/__deprecated__/renderer/components/core/icon/icon-type.ts @@ -128,4 +128,6 @@ export enum IconType { Conversation, Exclamation, DataMigration, + RecoveryModeWhite, + RecoveryModeBlack, } diff --git a/libs/core/__deprecated__/renderer/components/core/icon/icon.component.tsx b/libs/core/__deprecated__/renderer/components/core/icon/icon.component.tsx index 0faccd2634..526f421f29 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/icon.component.tsx +++ b/libs/core/__deprecated__/renderer/components/core/icon/icon.component.tsx @@ -21,7 +21,8 @@ export enum IconSize { Small = 1.6, Medium = 2.4, Big = 2.8, - Bigger = 3.2, + Large = 3.2, + ExtraLarge = 3.6, } export interface Props { diff --git a/libs/core/__deprecated__/renderer/components/core/icon/icon.config.ts b/libs/core/__deprecated__/renderer/components/core/icon/icon.config.ts index f6688c1e98..495c2f9a15 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/icon.config.ts +++ b/libs/core/__deprecated__/renderer/components/core/icon/icon.config.ts @@ -126,6 +126,8 @@ import MarkAsUnread from "Core/__deprecated__/renderer/svg/mark-as-unread.svg" import Conversation from "Core/__deprecated__/renderer/svg/conversation.svg" import Exclamation from "Core/__deprecated__/renderer/svg/exclamation.svg" import DataMigration from "../../../../../../generic-view/ui/src/lib/icon/svg/data-migration.svg" +import RecoveryModeWhite from "../../../../../../generic-view/ui/src/lib/icon/svg/recovery-mode-white.svg" +import RecoveryModeBlack from "../../../../../../generic-view/ui/src/lib/icon/svg/recovery-mode-black.svg" import { FunctionComponent } from "Core/core/types/function-component.interface" import { IconType } from "Core/__deprecated__/renderer/components/core/icon/icon-type" @@ -494,6 +496,8 @@ const typeToIcon: Partial> = { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment [IconType.Exclamation]: Exclamation, [IconType.DataMigration]: DataMigration, + [IconType.RecoveryModeWhite]: RecoveryModeWhite, + [IconType.RecoveryModeBlack]: RecoveryModeBlack, } export const getIconType = ( diff --git a/libs/core/__deprecated__/renderer/components/core/icon/icon.stories.tsx b/libs/core/__deprecated__/renderer/components/core/icon/icon.stories.tsx index 7f18e6f77f..19db96195b 100644 --- a/libs/core/__deprecated__/renderer/components/core/icon/icon.stories.tsx +++ b/libs/core/__deprecated__/renderer/components/core/icon/icon.stories.tsx @@ -3,18 +3,18 @@ * For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md */ -import { storiesOf } from "@storybook/react" import * as React from "react" +import styled from "styled-components" +import { storiesOf } from "@storybook/react" +import { DeviceType } from "device-protocol/models" import Icon, { IconSize, } from "Core/__deprecated__/renderer/components/core/icon/icon.component" -import styled from "styled-components" import StoryContainer from "Core/__deprecated__/renderer/components/storybook/story-container.component" import Story from "Core/__deprecated__/renderer/components/storybook/story.component" import BatteryIcon from "Core/__deprecated__/renderer/components/core/icon/battery-icon.component" import RangeIcon from "Core/__deprecated__/renderer/components/core/icon/range-icon.component" import { IconType } from "Core/__deprecated__/renderer/components/core/icon/icon-type" -import { DeviceType } from "Core/device" const CustomIcon = styled(Icon)` height: 3rem; diff --git a/libs/core/__deprecated__/renderer/components/core/modal/modal.helpers.tsx b/libs/core/__deprecated__/renderer/components/core/modal/modal.helpers.tsx index 7776391ee5..2b243da8f6 100644 --- a/libs/core/__deprecated__/renderer/components/core/modal/modal.helpers.tsx +++ b/libs/core/__deprecated__/renderer/components/core/modal/modal.helpers.tsx @@ -29,6 +29,11 @@ export const getModalSize = (size: ModalSize) => { return css` width: 59rem; ` + case ModalSize.MediumNew: + return css` + width: 56.6rem; + padding: 2.4rem; + ` case ModalSize.Large: return css` width: 101rem; diff --git a/libs/core/__deprecated__/renderer/components/core/modal/modal.interface.ts b/libs/core/__deprecated__/renderer/components/core/modal/modal.interface.ts index 08ce169e61..5d431d73c6 100644 --- a/libs/core/__deprecated__/renderer/components/core/modal/modal.interface.ts +++ b/libs/core/__deprecated__/renderer/components/core/modal/modal.interface.ts @@ -7,6 +7,7 @@ export enum ModalSize { VerySmall, Small, Medium, + MediumNew, Large, } diff --git a/libs/core/__deprecated__/renderer/components/rest/menu/__snapshots__/menu.test.tsx.snap b/libs/core/__deprecated__/renderer/components/rest/menu/__snapshots__/menu.test.tsx.snap index a6e7e87713..2dd3575d7f 100644 --- a/libs/core/__deprecated__/renderer/components/rest/menu/__snapshots__/menu.test.tsx.snap +++ b/libs/core/__deprecated__/renderer/components/rest/menu/__snapshots__/menu.test.tsx.snap @@ -225,6 +225,10 @@ exports[`Device: Mudita harmony matches snapshot 1`] = ` color: #6a6a6a; } +.c12.active { + pointer-events: all; +} + .c7 { margin: 0 0.8rem 0 0; } @@ -372,11 +376,12 @@ exports[`Device: Mudita harmony matches snapshot 1`] = `
- +
@@ -793,7 +798,7 @@ exports[`Device: Mudita pure matches snapshot 1`] = ` class="c8 c9" color="primary" > - [value] module.help + [value] module.help.v2

diff --git a/libs/core/__deprecated__/renderer/components/rest/menu/menu-bottom.component.tsx b/libs/core/__deprecated__/renderer/components/rest/menu/menu-bottom.component.tsx index 22b402acbc..bbc15738dd 100644 --- a/libs/core/__deprecated__/renderer/components/rest/menu/menu-bottom.component.tsx +++ b/libs/core/__deprecated__/renderer/components/rest/menu/menu-bottom.component.tsx @@ -4,6 +4,14 @@ */ import React from "react" +import { useSelector, useDispatch } from "react-redux" +import { useHistory } from "react-router-dom" +import styled from "styled-components" +import { + getDevicesSelector, + setSelectDeviceDrawerOpen, +} from "device-manager/feature" +import { activeDeviceIdSelector } from "active-device-registry/feature" import { FunctionComponent } from "Core/core/types/function-component.interface" import { MenuGroupTestIds } from "Core/__deprecated__/renderer/components/rest/menu/menu-group-test-ids.enum" import Loader from "Core/__deprecated__/renderer/components/core/loader/loader.component" @@ -12,19 +20,13 @@ import Text, { TextDisplayStyle, } from "Core/__deprecated__/renderer/components/core/text/text.component" import { intl } from "Core/__deprecated__/renderer/utils/intl" -import styled from "styled-components" import { IconType } from "Core/__deprecated__/renderer/components/core/icon/icon-type" import ButtonComponent from "Core/__deprecated__/renderer/components/core/button/button.component" -import { useSelector, useDispatch } from "react-redux" -import { getDevicesSelector } from "Core/device-manager/selectors/get-devices.selector" -import { useHistory } from "react-router-dom" import { URL_DISCOVERY_DEVICE } from "Core/__deprecated__/renderer/constants/urls" import { DisplayStyle } from "Core/__deprecated__/renderer/components/core/button/button.config" import { Dispatch } from "Core/__deprecated__/renderer/store" import { getDeviceInitializationStatus } from "Core/device-initialization/selectors/get-device-initialization-status.selector" import { DeviceInitializationStatus } from "Core/device-initialization/reducers/device-initialization.interface" -import { setSelectDeviceDrawerOpen } from "Core/device-select/actions/set-select-device-drawer-open.action" -import { activeDeviceIdSelector } from "Core/device-manager/selectors/active-device-id.selector" import { useCustomerSupportIsSending } from "Core/__deprecated__/renderer/components/rest/menu/hooks/use-customer-support-is-sending" const SyncProgressWrapper = styled.div` diff --git a/libs/core/__deprecated__/renderer/components/rest/menu/menu-group-test-ids.enum.ts b/libs/core/__deprecated__/renderer/components/rest/menu/menu-group-test-ids.enum.ts index a176ce6c11..5a392d9027 100644 --- a/libs/core/__deprecated__/renderer/components/rest/menu/menu-group-test-ids.enum.ts +++ b/libs/core/__deprecated__/renderer/components/rest/menu/menu-group-test-ids.enum.ts @@ -18,4 +18,5 @@ export enum MenuGroupTestIds { Sync = "sync-info", DataMigration = "data-migration-link", DeviceSelectionButton = "menu-group_device-selection-button", + RecoveryMode = "recovery-mode-link", } diff --git a/libs/core/__deprecated__/renderer/components/rest/menu/menu-group.component.tsx b/libs/core/__deprecated__/renderer/components/rest/menu/menu-group.component.tsx index af08a347b4..ddb4685c34 100644 --- a/libs/core/__deprecated__/renderer/components/rest/menu/menu-group.component.tsx +++ b/libs/core/__deprecated__/renderer/components/rest/menu/menu-group.component.tsx @@ -4,7 +4,7 @@ */ import * as React from "react" -import { DeviceType } from "Core/device/constants" +import { DeviceType } from "device-protocol/models" import Button from "Core/__deprecated__/renderer/components/core/button/button.component" import { DisplayStyle } from "Core/__deprecated__/renderer/components/core/button/button.config" import Text, { @@ -15,9 +15,7 @@ import { FunctionComponent } from "Core/core/types/function-component.interface" import { IconSize } from "Core/__deprecated__/renderer/components/core/icon/icon.component" import RangeIcon from "Core/__deprecated__/renderer/components/core/icon/range-icon.component" import BatteryIcon from "Core/__deprecated__/renderer/components/core/icon/battery-icon.component" -import { views } from "Core/__deprecated__/renderer/constants/views" -import { ipcRenderer } from "electron-better-ipc" -import { HelpActions } from "Core/__deprecated__/common/enums/help-actions.enum" +import { View } from "Core/__deprecated__/renderer/constants/views" import { HeaderIcon, HeaderIconBg, @@ -27,7 +25,6 @@ import { LinkWrapper, } from "Core/__deprecated__/renderer/components/rest/menu/menu-group.styled" import { IconType } from "Core/__deprecated__/renderer/components/core/icon/icon-type" -import { View } from "Core/__deprecated__/renderer/constants/views" import { NotificationBadge } from "Core/notification/components" interface MenuGroupProps extends MenuElement { @@ -84,47 +81,40 @@ const MenuGroup: FunctionComponent = ({ .filter(({ visibleOn }) => visibleOn && deviceType ? visibleOn.includes(deviceType) : true ) - .map(({ button, icon, testId, viewKey }, index) => { - const buttonMenuConfig = { - nav: true, - displayStyle: DisplayStyle.MenuLink, - Icon: icon, - iconSize: IconSize.Bigger, - ...(typeof button.label === "string" - ? { label: button.label } - : { labelMessage: button.label }), - } - if (button === views.help) { - const openHelpWindow = () => - ipcRenderer.callMain(HelpActions.OpenWindow) + .map( + ( + { button, icon, testId, disableWhenActive = true, viewKey }, + index + ) => { + const buttonMenuConfig = { + nav: true, + displayStyle: DisplayStyle.MenuLink, + Icon: icon, + iconSize: IconSize.Large, + ...(typeof button.label === "string" + ? { label: button.label } + : { labelMessage: button.label }), + disableWhenActive, + } return ( -