diff --git a/.depcheckrc.yaml b/.depcheckrc.yaml index 1388bc7bf..f311d92ec 100644 --- a/.depcheckrc.yaml +++ b/.depcheckrc.yaml @@ -1,26 +1,28 @@ ignores: [ - # These are dependencies for vite and vite plugins that depcheck doesn't recognize as being used - 'postcss-scss', - 'stylelint-order', - 'stylelint-config-recommended-scss', - 'stylelint-declaration-strict-value', - 'stylelint-scss', - '@vitest/coverage-c8', - # This is used by commitlint in .commitlintrc.js - '@commitlint/config-conventional', - # These are vite aliases / tsconfig paths that point to specific local directories - # Note the \ is necessary to escape the # or the ignore doesn't work - '\#src', - '\#test', - '\#types', - '\#components', - '\#utils', - # This is used in src/styles, which recognizes absolute paths from the repo root - 'src', - # To support e2e-reports - 'allure-commandline', - # To run linting checks - 'npm-run-all', - # SW code is injected at build time - 'virtual:pwa-register' -] + # These are dependencies for vite and vite plugins that depcheck doesn't recognize as being used + 'postcss-scss', + 'stylelint-order', + 'stylelint-config-recommended-scss', + 'stylelint-declaration-strict-value', + 'stylelint-scss', + '@vitest/coverage-c8', + # This is used by commitlint in .commitlintrc.js + '@commitlint/config-conventional', + # These are vite aliases / tsconfig paths that point to specific local directories + # Note the \ is necessary to escape the # or the ignore doesn't work + '\#src', + '\#test', + '\#types', + '\#components', + '\#utils', + # This is used in src/styles, which recognizes absolute paths from the repo root + 'src', + # To support e2e-reports + 'allure-commandline', + '@codeceptjs/allure-legacy', + 'faker', + # To run linting checks + 'npm-run-all', + # SW code is injected at build time + 'virtual:pwa-register', + ] diff --git a/.github/workflows/codeceptjs.yml b/.github/workflows/codeceptjs.yml index c094b0a7d..d3f896f33 100644 --- a/.github/workflows/codeceptjs.yml +++ b/.github/workflows/codeceptjs.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | yarn - npm install wait-on -g + yarn global add wait-on - name: Start preview server run: yarn start:test & - name: Run tests diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 6ec4f8274..852640c06 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -4,7 +4,7 @@ on: [pull_request] jobs: lint: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cb3177df1..4f980463f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,7 +4,7 @@ on: [pull_request] jobs: build: - runs-on: macos-latest + runs-on: ubuntu-latest strategy: matrix: diff --git a/CHANGELOG.md b/CHANGELOG.md index cd2df1ef4..f63f9ec0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [4.6.3](https://github.com/jwplayer/ott-web-app/compare/v4.6.2...v4.6.3) (2023-05-08) + + +### Bug Fixes + +* **e2e:** fix tests ([4fdfa79](https://github.com/jwplayer/ott-web-app/commit/4fdfa796c2e5797a496f4abd714b2786eada47a8)) + + + ## [4.6.2](https://github.com/jwplayer/ott-web-app/compare/v4.6.1...v4.6.2) (2023-04-21) diff --git a/docs/backend-services.md b/docs/backend-services.md index a967cd65a..bdf863799 100644 --- a/docs/backend-services.md +++ b/docs/backend-services.md @@ -4,12 +4,11 @@ The application is built as a single page web app that can run without its own d hosting it with a very simple, static host, like github pages. The server serves the static web content and the frontend calls the [JW Player Delivery API](https://developer.jwplayer.com/jwplayer/docs) directly. However, for additional functionality, the application can also connect to other backends to provide user -accounts / authentication, subscription management, and checkout flows. - +accounts / authentication, subscription management, and checkout flows. ## Roles and Functions -The available backend integrations serve 3 main roles, Accounts, Subscription, and Checkout. Below are the methods +The available backend integrations serve 3 main roles: Accounts, Subscription, and Checkout. Below are the methods that any backend integration needs to support broken down by role: - [Account](src/services/account.service.ts) @@ -48,4 +47,4 @@ The OTT Web App is optimized to work with JWP authentication, subscriptions, and ### Cleeng (https://developers.cleeng.com/docs) -The Web App was also developed with support for Cleeng. Cleeng is a 3rd party platform that also provides support for the 3 functional roles above. +The Web App was also developed with support for Cleeng. Cleeng is a 3rd party platform that also provides support for the 3 functional roles above. diff --git a/docs/build-from-source.md b/docs/build-from-source.md index 0384af66e..ad5534de1 100644 --- a/docs/build-from-source.md +++ b/docs/build-from-source.md @@ -27,13 +27,12 @@ $ cd ott-web-app $ yarn --ignore-optional ``` -> **NOTE**: Some of the [easy deployments](easy-deployments.md) instructions require installing these optional dependencies. Use the `yarn` command to install all dependencies. The `yarn` command can be run even if `yarn --ignore-optional` has been previously run. +> **NOTE**: Some of the [easy deployments](easy-deployments.md) instructions require installing these optional dependencies. Use the `yarn` command to install all dependencies. The `yarn` command can be run even if `yarn --ignore-optional` has been previously run. -3. Create or update the .ini files in `/ini` for the modes you will be running in (probably dev and prod.) - You can copy the ini file from `/ini/templates` into `/ini`. The files in `/ini` are git-ignored, so you do not need to worry about account values in source control, but you will need to recreate the ini files each time you make a fresh checkout of the repository. - - The .ini files provide startup values to the application such as which app config to load by default. See [initialization-file](initialization-file.md) for more details. +3. Create or update the .ini files in `/ini` for the modes you will be running in (probably dev and prod). + You can copy the ini file from `/ini/templates` into `/ini`. The files in `/ini` are git-ignored, so you do not need to worry about account values in source control, but you will need to recreate the ini files each time you make a fresh checkout of the repository. + The .ini files provide startup values to the application such as which app config to load by default. See [initialization-file](initialization-file.md) for more details. 4. Start the local development server. @@ -41,11 +40,12 @@ $ yarn --ignore-optional $ yarn start ``` -If you encounter any errors, make sure you have correctly set the `defaultConfigSource` in `/ini/.webapp.dev.ini` to point to a valid app config from your JWP account. -> **NOTE:** Only use the development server for development purposes. The development server is not optimized for production usage. +If you encounter any errors, make sure you have correctly set the `defaultConfigSource` in `/ini/.webapp.dev.ini` to point to a valid app config from your JWP account. + +> **NOTE:** Only use the development server for development purposes. The development server is not optimized for production usage. 5. Build a deployable version of the JW OTT Webapp source code.

This command creates a new folder in the projects root folder named **build**. - The `public` folder from the build directory can be uploaded to any static hosting provider to run the web app from that host. + The `public` folder from the build directory can be uploaded to any static hosting provider to run the web app from that host. ```shell $ yarn build @@ -58,7 +58,7 @@ If you encounter any errors, first check to make sure you've properly updated `/ ## Modes We make use of [Vite's 'mode' concept](https://vitejs.dev/guide/env-and-mode.html#modes) to cleanly separate different deployments. -For most cases, you will want to use `dev`, `test`, or `prod` modes. The supported modes are described below. +For most cases, you will want to use `dev`, `test`, or `prod` modes. The supported modes are described below. Please keep in mind that there is a nuanced difference between vite `mode` and whether you are running a development or production build as determined by [`NODE_ENV`](https://nodejs.dev/en/learn/nodejs-the-difference-between-development-and-production/). Mode can be whatever different deployment environments that our application can be run in, while the build type will always be either `development` or `production`. @@ -66,12 +66,12 @@ Typically when you run the development server using `yarn start`, it will be a ` Production builds optimize code and minimize debug information, while development builds are made for developers to dig into. -* **dev** - used for developers to locally develop, test, and debug code. Has the most debug information, including a config selector to help developers quickly switch between app configs. Will allow any app config to be loaded. -* **test** - used when running unit and e2e tests. Should typically be run as a production build. Will only load a select list of test app configs -* **prod** - default used when running `yarn build` to create compiled code for production hosting. You should make sure to update the prod .ini file to only allow app configs from your account. -* **demo** - used for the [JWP preview site](https://app-preview.jwplayer.com/) and includes a dialog to switch between app configs. Will allow any app-config to be loaded and does not have a default config. -* **preview** - used for github PR previews. Behaves like a hybrid between dev and demo. -* **jwdev** - this mode is for running code on JW's internal dev environment. It will only work for JW employees on the internal network. +- **dev** - used for developers to locally develop, test, and debug code. Has the most debug information, including a config selector to help developers quickly switch between app configs. Will allow any app config to be loaded. +- **test** - used when running unit and e2e tests. Should typically be run as a production build. Will only load a select list of test app configs. +- **prod** - default used when running `yarn build` to create compiled code for production hosting. You should make sure to update the prod .ini file to only allow app configs from your account. +- **demo** - used for the [JWP preview site](https://app-preview.jwplayer.com/) and includes a dialog to switch between app configs. Will allow any app-config to be loaded and does not have a default config. +- **preview** - used for github PR previews. Behaves like a hybrid between dev and demo. +- **jwdev** - this mode is for running code on JW's internal dev environment. It will only work for JW employees on the internal network. ## Env Variables @@ -81,11 +81,11 @@ These values are then defacto constants, which means code optimizations can remo For non-sensitive values, you can add them directly to the appropriate .env file for each mode. For sensitive values, if building with github actions we recommend using [github secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) and setting them in the [build action environment](https://docs.github.com/en/actions/learn-github-actions/variables). -You can see an example of how these are used in our [Firebase Live / Preview actions.](https://github.com/jwplayer/ott-web-app/blob/develop/.github/workflows/firebase-live.yml#L14) +You can see an example of how these are used in our [Firebase Live / Preview actions.](https://github.com/jwplayer/ott-web-app/blob/develop/.github/workflows/firebase-live.yml#L14) -If building manually, you can create an .env.[mode].local file and add the values there. These files are git ignored which will prevent leaking your secrets to version control. +If building manually, you can create an .env.[mode].local file and add the values there. These files are git ignored which will prevent leaking your secrets to version control. -> Note: env variables must begin with the 'APP_' prefix or they are ignored by our vite configuration. +> Note: env variables must begin with the 'APP\_' prefix or they are ignored by our vite configuration. ### APP_DEFAULT_CONFIG_SOURCE @@ -118,7 +118,7 @@ If you link directly to your JWP cloud player using the [APP_PLAYER_ID](#app_pla It is recommended that this value be provided via a .env.local file or a github secret to avoid saving it in version control. If you are using pre-compiled builds instead of building the code yourself, you can also set this value with the [playerLicenseKey ini setting](initialization-file.md#playerLicenseKey). -Keep in mind, if the [playerLicenseKey ini setting](initialization-file.md#playerLicenseKey) is provided, it will be used even if the `APP_PLAYER_LICENSE_KEY` environment variable is set. +Keep in mind, if the [playerLicenseKey ini setting](initialization-file.md#playerLicenseKey) is provided, it will be used even if the `APP_PLAYER_LICENSE_KEY` environment variable is set. ### APP_GITHUB_PUBLIC_BASE_URL diff --git a/docs/configuration.md b/docs/configuration.md index 3ec811e11..506121e23 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -9,20 +9,19 @@ Which app config file the application uses is determined by the [ini file](initi You can specify the default that the application starts with and also which config, if any, it will allow to be set using the [`app-config=` query param](#switching-between-app-configs). The location is usually specified by the 8-character ID (i.e. `gnnuzabk`) of the App Config from your JWP account, in which case the file will be loaded from the JW Player App Config delivery endpoint (i.e. `https://cdn.jwplayer.com/apps/configs/gnnuzabk.json`). -You may also specify a relative or absolute URL. +You may also specify a relative or absolute URL. ### Switching between app configs -As mentioned above, if you have 1 or more additional allowed sources (see additionalAllowedConfigSources in [`initialization-file`](initialization-file.md)), you can switch between them by adding `app-config=` as a query parameter in the web app URL in your browser (i.e. `https:///?app-config=gnnuzabk`.) +As mentioned above, if you have 1 or more additional allowed sources (see additionalAllowedConfigSources in [`initialization-file`](initialization-file.md)), you can switch between them by adding `app-config=` as a query parameter in the web app URL in your browser (i.e. `https:///?app-config=gnnuzabk`). The parameter is automatically evaluated, loaded, and stored in browser session storage and should remain part of the url as the user navigates around the site. ->*Note: Be aware that this mechanism only sets the config for the local machine, browser, and session that you are accessing the site with and it does not change the default hosted app for other users.* +> _Note: Be aware that this mechanism only sets the config for the local machine, browser, and session that you are accessing the site with and it does not change the default hosted app for other users._ Even sharing URL's should work as long as the query parameter of the desired config is part of the URL. However, once the query parameter is removed and the stored value in the session is released, the application will revert to loading the default config source. ->*Note: to clear the value from session storage and return to the default, you can navigate to the site with a blank query parameter value (i.e. `?app-config=`)* - +> _Note: to clear the value from session storage and return to the default, you can navigate to the site with a blank query parameter value (i.e. `?app-config=`)_ ## Available Configuration Parameters @@ -107,10 +106,10 @@ Use the `content` array to define which and how content playlists should be disp }, { "contentId": "WXu7kuaW" "type": "playlist" - }] + }] } -``` +``` --- @@ -122,7 +121,7 @@ The eight-character Playlists IDs from the JW Player dashboard. These IDs popula **content[].type** -It is possible to use 'playlist', 'continue_watching' or 'favorites' as a type. With this, you can change the position of the shelves and turn on/off extra `continue_watching` and `favorites` shelves. +It is possible to use 'playlist', 'continue_watching' or 'favorites' as a type. With this, you can change the position of the shelves and turn on/off extra `continue_watching` and `favorites` shelves. If you want to include `favorites` / `continue_watching` shelf, you should also add a corresponding playlist with `watchlist` type to features section (`features.favoritesList` and `features.continueWatchingList`). To exclude the shelves, remove a corresponding array item and a playlist in `features`. @@ -184,7 +183,7 @@ Specify the color in hexadecimal format. For example, if you want bright yellow, **styling.headerBackground** (optional) -Use this parameter to change the background color of the header. By default, the header is transparent. Recommended is to use a HEX color (e.g. `#1a1a1a`) so that the contrast color of the buttons and links can be calculated. +Use this parameter to change the background color of the header. By default, the header is transparent. Recommended is to use a HEX color (e.g. `#1a1a1a`) so that the contrast color of the buttons and links can be calculated. --- @@ -208,7 +207,6 @@ Use the `features` object to define extra properties for your app. --- - **features.recommendationsPlaylist** (optional) The eight-character Playlist ID of the Recommendations playlist that you want to use to populate the "Related Videos" shelf in your site. Note that Recommendations requires a JW Player Enterprise license. For more information about Recommendations playlists, see [this JW Player Support article](https://support.jwplayer.com/customer/portal/articles/2191721-jw-recommendations). @@ -229,7 +227,7 @@ The eight-character Playlist ID of the Watchlist playlist that you want to use t **features.continueWatchingList** (optional) -The eight-character Playlist ID of the Watchlist playlist that you want to use to populate the "Continue Watching" shelf in your site. +The eight-character Playlist ID of the Watchlist playlist that you want to use to populate the "Continue Watching" shelf in your site. --- @@ -301,14 +299,14 @@ This setting determines which Cleeng mediastore URL is used. If false or not def **integrations.cleeng.monthlyOffer** (optional) -If Cleeng is enabled, and you want to show the Payments and Subscription functionality, you need to include at least 1 offer ID (either this or the yearly offer property.) The application uses this ID to map to an offer that you've configured in your Cleeng environment under Offers to represent your monthly subscription. Note that the only the data used from the Cleeng offer is the price, the free days, and the free period and the app does not verify if the offer length is actually monthly. If no monthly or yearly offer is configured, the Payments section will not be shown. +If Cleeng is enabled, and you want to show the Payments and Subscription functionality, you need to include at least 1 offer ID (either this or the yearly offer property.) The application uses this ID to map to an offer that you've configured in your Cleeng environment under Offers to represent your monthly subscription. Note that the only the data used from the Cleeng offer is the price, the free days, and the free period and the app does not verify if the offer length is actually monthly. If no monthly or yearly offer is configured, the Payments section will not be shown. --- **integrations.cleeng.yearlyOffer** (optional) If Cleeng is enabled, and you want to show the Payments and Subscription functionality, you need to include at least 1 -offer ID (either this or the monthly offer property.) The application uses this ID to map to an offer that you've +offer ID (either this or the monthly offer property.) The application uses this ID to map to an offer that you've configured in your Cleeng environment under Offers to represent your yearly subscription. Note that the only the data used from the Cleeng offer is the price, the free days, and the free period and the app does not verify if the offer length is actually yearly. If no monthly or yearly offer is configured, the Payments section will not be shown. diff --git a/docs/developer-guidelines.md b/docs/developer-guidelines.md index 23e664247..5352d71a2 100644 --- a/docs/developer-guidelines.md +++ b/docs/developer-guidelines.md @@ -6,16 +6,17 @@ - Run the e2e tests through `yarn codecept:mobile` and `yarn codecept:desktop` - Format the code through `yarn format` (or automatically do it via git hooks) - Lint through `yarn lint` (eslint, prettier, stylelint and tsc checks) -- The JW organization requires personal access tokens for all of their repositories. In order to create a branch or pull request you'll need to [Generate a Personal Access Token](https://github.com/settings/tokens) and then [store it in your git config](https://stackoverflow.com/questions/46645843/where-to-store-my-git-personal-access-token/67360592). (For token permissions, `repo` should be sufficient.) +- The JW organization requires personal access tokens for all of their repositories. In order to create a branch or pull request you'll need to [Generate a Personal Access Token](https://github.com/settings/tokens) and then [store it in your git config](https://stackoverflow.com/questions/46645843/where-to-store-my-git-personal-access-token/67360592). (For token permissions, `repo` should be sufficient). ## Versioning and Changelog -We use the [TriPSs/conventional-changelog-action](https://github.com/TriPSs/conventional-changelog-action) github [action](https://github.com/jwplayer/ott-web-app/actions/workflows/bump-version.yml) to do an automated version increment for any commit to the develop branch. The type of version increment will be determined by the commit message(s) in the code being added as follows (see [Convential Commits](https://www.conventionalcommits.org/en/v1.0.0/) for more details): -* `fix:` - perform a patch bump -* `feat:` - perform a minor bump -* `chore:` - no version change -* commit body contains `BREAKING CHANGE:` - perform a major bump -* `!:` (i.e. `feat!:`) - perform a major bump +We use the [TriPSs/conventional-changelog-action](https://github.com/TriPSs/conventional-changelog-action) github [action](https://github.com/jwplayer/ott-web-app/actions/workflows/bump-version.yml) to do an automated version increment for any commit to the develop branch. The type of version increment will be determined by the commit message(s) in the code being added as follows (see [Convential Commits](https://www.conventionalcommits.org/en/v1.0.0/) for more details): + +- `fix:` - perform a patch bump +- `feat:` - perform a minor bump +- `chore:` - no version change +- commit body contains `BREAKING CHANGE:` - perform a major bump +- `!:` (i.e. `feat!:`) - perform a major bump In case there are multiple commits being merged, the biggest type of bump will be performed. @@ -45,14 +46,14 @@ The subject line of the commit message cannot be longer 100 characters. This all Please use one of the following: -* **feat**: A new feature -* **fix**: A bug fix -* **docs**: Documentation only changes -* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) -* **refactor**: A code change that neither fixes a bug or adds a feature -* **perf**: A code change that improves performance -* **test**: Adding missing tests -* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation +- **feat**: A new feature +- **fix**: A bug fix +- **docs**: Documentation only changes +- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- **refactor**: A code change that neither fixes a bug or adds a feature +- **perf**: A code change that improves performance +- **test**: Adding missing tests +- **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation ### Scope @@ -82,9 +83,9 @@ The allowed scopes are: The subject contains a succinct description of the change: -* Use the imperative, present tense: "change" not "changed" nor "changes". -* Don't capitalize the first letter. -* Do not add a dot (.) at the end. +- Use the imperative, present tense: "change" not "changed" nor "changes". +- Don't capitalize the first letter. +- Do not add a dot (.) at the end. ### Body @@ -126,7 +127,7 @@ The footer should contain any information about **Breaking Changes** and is also /App.tsx - The main React component which renders the app /index.tsx - The entrypoint /registerSer... - Script or SPA functionality -/test - Data and scrips for unit and e2e testing +/test - Data and scripts for unit and e2e testing /test-e2e - End to end tests and scripts /types - Global type definitions /.env<.mode> - Environment variables for different Vite modes diff --git a/docs/e2e.md b/docs/e2e.md index 02d6f7090..995cacbdf 100644 --- a/docs/e2e.md +++ b/docs/e2e.md @@ -24,7 +24,7 @@ In the `data` folder we store ott-app configs necessary for testing purposes. To ## Test suite -Each test suite is a separate file located in the `tests` folder. It is necessary to label the suite with the following feature code: `Feature('account').retry(3);` . In order to reduce the chance of unintended failures it is also better to define retry count. This way a test will be relaunched several times in case it failed. +Each test suite is a separate file located in the `tests` folder. It is necessary to label the suite with the following feature code: `Feature('account').retry(3);`. In order to reduce the chance of unintended failures it is also better to define retry count. This way a test will be relaunched several times in case it failed. **TODO:** use `allure.createStep` to have readable steps in allure reports. [Read more.](https://codecept.io/plugins/#allure) @@ -36,16 +36,16 @@ We use several workers to launch tests for each platform. That increases the spe Basic commands: -`yarn codecept:mobile` - to run tests for a mobile device -`yarn codecept:desktop`: - to run tests for desktop -`yarn serve-report:mobile` - to serve allure report from "./output/mobile" folder -`yarn serve-report:desktop` - to serve allure report from "./output/desktop" folder -`yarn codecept-serve:mobile` - to run desktop tests and serve the report -`yarn codecept-serve:desktop` - to run mobile tests and serve the report +- `yarn codecept:mobile` - to run tests for a mobile device +- `yarn codecept:desktop` - to run tests for desktop +- `yarn serve-report:mobile` - to serve allure report from "./output/mobile" folder +- `yarn serve-report:desktop` - to serve allure report from "./output/desktop" folder +- `yarn codecept-serve:mobile` - to run desktop tests and serve the report +- `yarn codecept-serve:desktop` - to run mobile tests and serve the report ## GitHub Actions -We have two actions: one for desktop and one for mobile device. Each one runs independently. After the action run it is possible to download an artifact with an allure report and build a nice report locally. +We have two actions: one for desktop and one for mobile device. Each one runs independently. After the action run it is possible to download an artifact with an allure report and build a nice report locally. To do it on Mac: `allure serve ~/Downloads/allure-report-desktop` @@ -56,4 +56,4 @@ To serve allure reports locally `allure-commandline` package should be installed 1. Install Java 8 (for Mac homebrew `adoptopenjdk8` package can be used) 2. `yarn install` 3. Install `allure-commandline` globally (can help in the future to serve downloaded artifacts) -4. Run `yarn codecept-serve:desktop` +4. Run `yarn codecept-serve:desktop` diff --git a/docs/easy-deployments.md b/docs/easy-deployments.md index 7ba7a1fe3..7a162d82b 100644 --- a/docs/easy-deployments.md +++ b/docs/easy-deployments.md @@ -9,20 +9,20 @@ The instructions in this document will help you deploy your fork of the ott-web- ## Supported Platforms -- [Google Firebase](#google-firebase): Free, easy to use [web hosting service](https://firebase.google.com/) with [integrations](https://firebase.google.com/docs/hosting/github-integration) to deploy directly from github. +- [Google Firebase](#google-firebase): Free, easy to use [web hosting service](https://firebase.google.com/) with [integrations](https://firebase.google.com/docs/hosting/github-integration) to deploy directly from github - [GitHub Pages](#github-pages): Static hosting [directly from a repository](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages) though with some limitations ### Google Firebase #### Technical Limitations -Firebase has both [free and paid plans](https://firebase.google.com/pricing). The [limits](https://firebase.google.com/docs/hosting/usage-quotas-pricing) are determined by Google and are likely to change and evolve, but at the moment they are based on the storage and data transfer per month. Note that storage limits are calculated including preview releases and old release versions, so you may want to [limit the retention](https://firebase.google.com/docs/hosting/manage-hosting-resources#release-storage-settings) of these on your project. +Firebase has both [free and paid plans](https://firebase.google.com/pricing). The [limits](https://firebase.google.com/docs/hosting/usage-quotas-pricing) are determined by Google and are likely to change and evolve, but at the moment they are based on the storage and data transfer per month. Note that storage limits are calculated including preview releases and old release versions, so you may want to [limit the retention](https://firebase.google.com/docs/hosting/manage-hosting-resources#release-storage-settings) of these on your project. #### Usage Instructions First, in your fork, you will need to update the project ID in [.firebaserc](.firebaserc). -The easiest way to deploy is to use the [Firebase-Github integration](https://firebase.google.com/docs/hosting/github-integration). You can find the action [.yml specifications here](https://github.com/marketplace/actions/deploy-to-firebase-hosting) to deploy to a preview channel for each PR and to the live channel for each merge to your main branch. If you want to manually setup the work, you can find those instructions [here](https://github.com/FirebaseExtended/action-hosting-deploy/blob/main/docs/service-account.md). +The easiest way to deploy is to use the [Firebase-Github integration](https://firebase.google.com/docs/hosting/github-integration). You can find the action [.yml specifications here](https://github.com/marketplace/actions/deploy-to-firebase-hosting) to deploy to a preview channel for each PR and to the live channel for each merge to your main branch. If you want to manually setup the work, you can find those instructions [here](https://github.com/FirebaseExtended/action-hosting-deploy/blob/main/docs/service-account.md). You can also manually deploy using the Firebase CLI, as described [here](https://firebase.google.com/docs/hosting/quickstart). @@ -30,24 +30,22 @@ You can also manually deploy using the Firebase CLI, as described [here](https:/ #### Technical Limitations -Github pages is bare bones static hosting, not optimized for single page apps. This means that urls do not automatically redirect to index.html. For this reason, the Github deploy scripts configure the application to use [hash routing](https://v5.reactrouter.com/web/api/HashRouter), which may be undesirable for production applications. +Github pages is bare bones static hosting, not optimized for single page apps. This means that urls do not automatically redirect to index.html. For this reason, the Github deploy scripts configure the application to use [hash routing](https://v5.reactrouter.com/web/api/HashRouter), which may be undesirable for production applications. -Github pages also has some [usage limits](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#usage-limits). These limits are determined by Github and are likely to change and evolve, but at the moment they are primarily on the repo size, the bandwidth, and the number of builds per hour. After reviewing the current Github pages limits, if you anticipate exceeding these, you should consider other paid hosting solutions. +Github pages also has some [usage limits](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#usage-limits). These limits are determined by Github and are likely to change and evolve, but at the moment they are primarily on the repo size, the bandwidth, and the number of builds per hour. After reviewing the current Github pages limits, if you anticipate exceeding these, you should consider other paid hosting solutions. #### Usage Instructions 1. (Optional) If you need a customization option, review `yarn deploy:github --help`. 2. Confirm that you can [build this project from source](./build-from-source.md). Be sure to install optional dependencies. 3. Enable the [Github Pages feature](https://docs.github.com/en/pages/getting-started-with-github-pages) for the `gh-pages` branch in your repository. -4. Run `yarn deploy:github`. Be sure to follow the instructions that appear on the screen. If you want to connect your github deployment to a custom domain remember to add `--custom-domain=mydomain.com` +4. Run `yarn deploy:github`. Be sure to follow the instructions that appear on the screen. If you want to connect your github deployment to a custom domain remember to add `--custom-domain=mydomain.com`. ### Technical Documentation The `yarn deploy:github` command executes a simple nodejs script located in `scripts/deploy-github.js`. The script executes the following commands: 1. Runs `yarn build` with [`APP_GITHUB_PUBLIC_BASE_URL`](build-from-source.md#APP_GITHUB_PUBLIC_BASE_URL) envvar. -2. Runs `yarn gh-pages -o origin -d build`.

You can change the remote from *origin* to *myremote* by running `yarn deploy:github --github-remote=myremote`. The `yarn deploy:github` command uses the GitHub remote to compute the default value for `APP_GITHUB_PUBLIC_BASE_URL`. - - ->**TIP**: Before each of the previous steps, the script will ask if you want to continue. You can prevent these confirmation inquiries by providing `--build` or `--deploy` arguments to `yarn deploy:github`. +2. Runs `yarn gh-pages -o origin -d build`.

You can change the remote from _origin_ to _myremote_ by running `yarn deploy:github --github-remote=myremote`. The `yarn deploy:github` command uses the GitHub remote to compute the default value for `APP_GITHUB_PUBLIC_BASE_URL`. +> **TIP**: Before each of the previous steps, the script will ask if you want to continue. You can prevent these confirmation inquiries by providing `--build` or `--deploy` arguments to `yarn deploy:github`. diff --git a/docs/features/related-videos.md b/docs/features/related-videos.md index 8dd19202b..abaf6dabc 100644 --- a/docs/features/related-videos.md +++ b/docs/features/related-videos.md @@ -4,11 +4,11 @@ Related videos are a shelf in the [video detail screen](video-detail.md) showing content with similar metadata. -Related videos are powered through [recommendation playlist](https://support.jwplayer.com/topics/recommendations) is used. +Related videos are powered through the [recommendation playlist](https://docs.jwplayer.com/platform/docs/vdh-create-a-recommendations-playlist) being used. ## Retrieve related videos -A [recommendations playlist](https://support.jwplayer.com/topics/recommendations) is used for the related videos shelf. The playlist id is retrieved from the [app config](/docs/configuration.md): `recommendationsPlaylist` +A [recommendations playlist](https://docs.jwplayer.com/platform/docs/vdh-create-a-recommendations-playlist) is used for the related videos shelf. The playlist id is retrieved from the [app config](/docs/configuration.md): `recommendationsPlaylist` Queries are done using the [playlist endpoint](https://developer.jwplayer.com/jwplayer/reference/get_v2-playlists-playlist-id): @@ -41,4 +41,4 @@ GET playlists/fuD6TWcf?related_media_id=dwEE1oBP ## Configuration -The feature can be enabled in the [app config](/docs/configuration.md) by setting `recommendationsPlaylist` to the ID of the recommendations playlist you want to use. +The feature can be enabled in the [app config](/docs/configuration.md) by setting `recommendationsPlaylist` to the ID of the recommendations playlist you want to use. diff --git a/docs/features/search.md b/docs/features/search.md index 1d1d390fe..de7ade121 100644 --- a/docs/features/search.md +++ b/docs/features/search.md @@ -2,13 +2,13 @@ ![Search](../_images/search.jpg) -Search is essentially a [library](shelves-and-libraries.md) screen that reacts to a search term. A search queries the media `title` and `description` fields. +Search is essentially a [library](shelves-and-libraries.md) screen that reacts to a search term. A search queries the media `title` and `description` fields. ## Retrieve search results -Like libraries, search results are coming from playlist: [a search playlist](https://support.jwplayer.com/articles/create-a-playlist). The playlist id is retrieved from the [app config](/docs/configuration.md): `searchPlaylist` +Like libraries, search results are coming from playlist: [a search playlist](https://docs.jwplayer.com/platform/docs/vdh-create-a-search-playlist). The playlist id is retrieved from the [app config](/docs/configuration.md): `searchPlaylist` -Search queries are done using the [GET playlist endpoint](https://developer.jwplayer.com/jwplayer/reference/get_v2-playlists-playlist-id): +Search queries are done using the [GET playlist endpoint](https://developer.jwplayer.com/jwplayer/reference/get_v2-playlists-playlist-id): ``` GET playlists/tQ832H1H?search=bunny @@ -35,4 +35,5 @@ GET playlists/tQ832H1H?search=bunny ``` ## Configuration -The feature can be enabled in the [app config](/docs/configuration.md) by setting `searchPlaylist` to the ID of the recommendations playlist you want to use. + +The feature can be enabled in the [app config](/docs/configuration.md) by setting `searchPlaylist` to the ID of the recommendations playlist you want to use. diff --git a/docs/features/series.md b/docs/features/series.md index eb6782f32..dd483a0e5 100644 --- a/docs/features/series.md +++ b/docs/features/series.md @@ -16,7 +16,7 @@ Customers can create a 'Series playlist' and set the sequences and episodes usin ### Creating series playlists in the dashboard -The [JW manual](https://support.jwplayer.com/articles/build-an-ott-apps-series-playlist) describes the following process to create a serie playlist. +The [JW manual](https://support.jwplayer.com/articles/build-an-ott-apps-series-playlist) describes the following process to create a series playlist. ### Series in libraries and shelves diff --git a/docs/features/shelves-and-libraries.md b/docs/features/shelves-and-libraries.md index 45770a586..0b6b7e671 100644 --- a/docs/features/shelves-and-libraries.md +++ b/docs/features/shelves-and-libraries.md @@ -1,6 +1,6 @@ # Video Shelves and Libraries -Shelves Libraries +Shelves Libraries ## Shelves @@ -15,13 +15,13 @@ There are some special shelves: - featured shelf: highlight special videos, manually curated and visualized in the top of the homepage - favorite shelf: a list of videos a user likes to watch in the future. See [Watchlist](user-watchlists.md) -- continue watching shelf: a list of videos a user has not completed yet. See [Watchlist](user-watchlists.md) +- continue watching shelf: a list of videos a user has not completed yet. See [Watchlist](user-watchlists.md) ## Libraries -A library allows viewers to browse all videos. The standard usage is: +A library allows viewers to browse all videos. The standard usage is: -- Different libraries per format e.g ‘movies’, ‘shorts’, ‘shows’ +- Different libraries per format e.g ‘movies’, ‘shorts’, ‘shows’ - About 50-500 items per library - 5-20 genre filters e.g ‘action’, ‘drama’, ‘comedy’ @@ -41,18 +41,18 @@ Videos are published to shelves and libraries using playlists: Each media item has poster images: - The static thumbnail is automatically taken from a frame of the video -- The motion thumbnail (mp4/no audio) that is automatically derived from the first 5 seconds of the video +- The motion thumbnail (mp4/no audio) that is automatically derived from the first 5 seconds of the video - It’s possible to choose a custom thumbnail. The static thumbnail can be selected from the stills of the media item. - It’s not possible to have no thumbnails. - The static thumbnails are automatically resized to 320px-1920px widths, keeping the image ratio stable. -The motion image is not used in the web app. +The motion image is not used in the web app. The JW Player dashboard, nor the web app support alternate video images at this moment. E.g. an hero image for the video detail page. ## Shelf and library configuration -Shelves and libraries can be defined in the [app config](/docs/configuration.md), rather than hardcoded. This allows customer to change the content from the JW Dashboard. The `filterTags` are used to define the filterbox in the library screen. +Shelves and libraries can be defined in the [app config](/docs/configuration.md), rather than hardcoded. This allows customer to change the content from the JW Dashboard. The `filterTags` are used to define the filterbox in the library screen. ``` { @@ -82,15 +82,15 @@ Shelves and libraries can be defined in the [app config](/docs/configuration.md) ## Retrieving shelf and library contents -Shelf and library contents are retrieved as a playlist. They can be retrieved with the Playlist API +Shelf and library contents are retrieved as a playlist. They can be retrieved with the Playlist API. ``` GET Playlist\ [{ "title":"Video Title", - "description":"Lorem ipsum dolor sit amet", “ + "description":"Lorem ipsum dolor sit amet", "images":[ - {"src":"./media/dwEE1oBP/poster.jpg?width=640" }, + {"src":"./media/dwEE1oBP/poster.jpg?width=640" }, {"src":"./media/dwEE1oBP/poster.jpg?width=1280" } {"src":"./media/dwEE1oBP/poster.mp4?width=1280" }] }, @@ -98,6 +98,6 @@ GET Playlist\ ] ``` -For large libraries, (>500) it is possible to paginate. +For large libraries, (>500) it is possible to paginate. -It is possible to query based on tags and custom parameters +It is possible to query based on tags and custom parameters. diff --git a/docs/features/user-watchlists.md b/docs/features/user-watchlists.md index 3c2af17ed..572f1ed22 100644 --- a/docs/features/user-watchlists.md +++ b/docs/features/user-watchlists.md @@ -20,7 +20,7 @@ This watchlist contains movies a user has not entirely watched. It has the follo **Across the app** -- A progress bar shows how much of the content a viewer has watched. +- A progress bar shows how much of the content a viewer has watched - When a partially watched video is completed, it is removed from the shelf and the progress bar disappears - Just started (<5%) and almost completed (>95%) plays are ignored for the best experience. - For series @@ -45,7 +45,7 @@ This watchlist contains movies a user has not entirely watched. It has the follo For non-logged in users, the watch history is stored clientside in local storage. -For logged in users, the favorites and watch history are stored server side at the subscription or authentication provider to enable **cross-device watch history** +For logged in users, the favorites and watch history are stored server side at the subscription or authentication provider to enable **cross-device watch history**. To ensure a **cross-device experience**, we standardize on the following dataformat: @@ -73,7 +73,12 @@ To ensure a **cross-device experience**, we standardize on the following datafor ## Watchlist playlist +<<<<<<< HEAD The media metadata for the stored media ids an be retrieved through a [watchlist playlist](https://developer.jwplayer.com/jwplayer/docs/creating-and-using-a-watchlist-playlist): +======= +The media metadata for the stored media ids can be retrieved through a [watchlist playlist](https://developer.jwplayer.com/jwplayer/docs/creating-and-using-a-watchlist-playlist): + +> > > > > > > develop ``` curl 'https://cdn.jwplayer.com/apps/watchlists/?media_ids=' @@ -96,7 +101,7 @@ The continue watching and favorites features can be enabled and disabled in the https://cleeng.com is a subscription management system, which pre-integrated in the web-app. -For Cleeng we store the watch history in the `customer externalData` attribute. See [here](https://developers.cleeng.com/reference/fetch-customers-data) +For Cleeng we store the watch history in the `customer externalData` attribute. See [here](https://developers.cleeng.com/reference/fetch-customers-data). ### Example Request diff --git a/docs/features/video-analytics.md b/docs/features/video-analytics.md index 6eb842c68..7a0a7d334 100644 --- a/docs/features/video-analytics.md +++ b/docs/features/video-analytics.md @@ -63,7 +63,7 @@ Each event comes with a set of data sent through the query parameters of the JWP - Media - The media that is being watched - Quantile - How much the user watched a particular movie -Theee metrics are described below. +These metrics are described below. ### Session Metrics @@ -119,7 +119,7 @@ Theee metrics are described below. | -------------------- | --- | ------------ | ---------------- | -------------------------- | ------------------------------------------------- | | Media ID | id | Yes | \[0-9a-zA-Z\]{8} | 9u6OHIO4 | A unique identifier for a JW Player media item. | | Media Title | t | Yes | \- | The Perfect Holiday Turkey | The provided title for the current playlist item. | -| Video Duration (sec) | vd | 1 | \- | 141 | Duration of the vide | +| Video Duration (sec) | vd | 1 | \- | 141 | Duration of the video | 1Only requied for the play event `s` diff --git a/docs/features/video-detail.md b/docs/features/video-detail.md index 8233c6ba1..554ad0ca0 100644 --- a/docs/features/video-detail.md +++ b/docs/features/video-detail.md @@ -1,6 +1,6 @@ # Video detail -A video detail page is where a viewer evaluates a published video, before deciding to play the video. +A video detail page is where a viewer evaluates a published video, before deciding to play the video. ![Video detail](./../_images/video-detail.jpg) @@ -16,31 +16,31 @@ This page displays attributes that are common to all videos, such as: ## Image -- The poster image is available in different resolutions +- The poster image is available in different resolutions. - Some platforms require alternate poster images. That needs to be solved with custom properties and a CMS that handles the images. ## Trailers -Customers can add movie trailers to a video through the a custom field `trailerId`. The trailer is just another media item to play. See example below. +Customers can add movie trailers to a video through the a custom field `trailerId`. The trailer is just another media item to play. See example below. ### Retrieving video detail data -Video metadata can be retrieved from [GET Media](https://developer.jwplayer.com/jwplayer/reference/get_v2-media-media-id) +Video metadata can be retrieved from [GET Media](https://developer.jwplayer.com/jwplayer/reference/get_v2-media-media-id) ``` GET media/dwEE1oBP { "title":"Video Title", - "description":"Lorem ipsum dolor sit amet", - "pubdate: 1226866558, - “duration:596, + "description":"Lorem ipsum dolor sit amet", + "pubdate: 1226866558, + “duration:596, "rating":"CC-BY", "genre":"Comedy", - "trailerId":”sQUr0MIH”, + "trailerId":”sQUr0MIH”, "images":[ - {"src":"./media/dwEE1oBP/poster.jpg?width=720" }, - {"src":"./media/dwEE1oBP/poster.jpg?width=1280" }], + {"src":"./media/dwEE1oBP/poster.jpg?width=720" }, + {"src":"./media/dwEE1oBP/poster.jpg?width=1280" }], "sources":[] } ``` diff --git a/docs/features/video-protection.md b/docs/features/video-protection.md index de1be1bd9..a5b587ff0 100644 --- a/docs/features/video-protection.md +++ b/docs/features/video-protection.md @@ -2,12 +2,12 @@ Videos can be protected in JW platform in two ways: -- **Signed URLs:** A player can only **access** video URLs from JW Player backend using a time-bound JWT token -- **DRM:** A player can only **play** videos using a time-bound decryption key. +- **Signed URLs:** A player can only **access** video URLs from JW Player backend using a time-bound JWT token. +- **DRM:** A player can only **play** videos using a time-bound decryption key. -The JW Web Player, as well as the other SDKs, supports these mechanismns out-the-box. However this requires a server side authorization service which is **NOT** part of the web app and needs to be **custom developed**. +The JW Web Player, as well as the other SDKs, supports these mechanismns out-of-the-box. However this requires a server side authorization service which is **NOT** part of the web app and needs to be **custom developed**. -This article outlines such authorization service should work. +This article outlines how such an authorization service should work. ## Signed URLs @@ -17,7 +17,7 @@ With [URL signing](https://support.jwplayer.com/articles/how-to-enable-url-token GET media/PEEzDfdA?token= { "title":"Video Title", - "description":"Lorem ipsum dolor sit amet", + "description":"Lorem ipsum dolor sit amet", "sources":[https://content.jwplatform.com/manifests/PEEzDfdA.m3u8?token=] } ``` @@ -45,11 +45,11 @@ The tokens are generated using the property API key. See [the documenation](http JW [supports](https://developer.jwplayer.com/jwplayer/docs/enable-drm-with-jw-stream) three DRM systems -* Widevine (Google ecosystem) -* PlayReady (Microsoft ecosystem) -* Fairplay (Apple ecosystem) +- Widevine (Google ecosystem) +- PlayReady (Microsoft ecosystem) +- Fairplay (Apple ecosystem) -These systems require a time-bound decryption key, which can be fetched from the license URL. +These systems require a time-bound decryption key, which can be fetched from the license URL. Also all DRM URLs require to be signed with a token. @@ -57,7 +57,7 @@ Also all DRM URLs require to be signed with a token. GET media/PEEzDfdA/drm/:drm_policy_id?token= { "title":"Video Title", - "description":"Lorem ipsum dolor sit amet", + "description":"Lorem ipsum dolor sit amet", "sources":[{ "drm":{ "file":":https://content.jwplatform.com/manifests/PEEzDfdA.m3u8?token=", @@ -77,19 +77,19 @@ The authorization service should generate the `SignedMediaURLs` based on: - the users authentication (who is the user) - the users entitlements (what did he buy) -The service interface could look like this: +The service interface could look like this: `GET /authorization//video-signature/` ### Video access models -The authorization service provides signed URLs based on the access model. Common access models are: +The authorization service provides signed URLs based on the access model. Common access models are: - Advertising-based (AVOD): all videos can be accessed, as they are served with advertisements - Authentication-based (AUTHVOD): videos can be accessed if the user is logged in - Subscription-based (SVOD): videos can be accessed if the user has a valid subscription -Note that there are many variations of these access models. +Note that there are many variations of these access models. ### Free content @@ -97,15 +97,15 @@ It's possible to have free content. This is indicated with media parameter `free ### Users and entitlements -The users and their entitlements are typically stored in a subscription management service like JWP or Cleeng. +The users and their entitlements are typically stored in a subscription management service like JWP or Cleeng. -Users and their entitlements might also be split: +Users and their entitlements might also be split: - Users at identity providers like Okta or Amazon Cognito - Entitlements at a subscription provider like JWP or Cleeng ### SVOD Optimization -Notice that each time a user accesses a video, the service would have to check against the subscription provider (e.g., JWP or Cleeng) to validate if there is a subscription. This request can be slow and might have consumption limits. +Notice that each time a user accesses a video, the service would have to check against the subscription provider (e.g., JWP or Cleeng) to validate if there is a subscription. This request can be slow and might have consumption limits. -To ensure a fast user experience this subscription status can be stored in ``UserSubscriptionToken``: a signed time-bound claim that the user has valid subscription. This claim would be exchanged when signing URLs. +To ensure a fast user experience this subscription status can be stored in `UserSubscriptionToken`: a signed time-bound claim that the user has valid subscription. This claim would be exchanged when signing URLs. diff --git a/docs/features/video-sharing.md b/docs/features/video-sharing.md index ce8e5b0f0..0949488dc 100644 --- a/docs/features/video-sharing.md +++ b/docs/features/video-sharing.md @@ -2,24 +2,25 @@ ![Share video](../_images/share-video.jpg) -Viewers can share a video: -- On the desktop this will copy the URL to the clipboard -- On mobile devices, this will share the URL through the device sharing window +Viewers can share a video: + +- On the desktop this will copy the URL to the clipboard +- On mobile devices, this will share the URL through the device sharing window ## Configuration -Sharing can be enabled/disabled in the [app config](/docs/configuration.md) +Sharing can be enabled/disabled in the [app config](/docs/configuration.md). ## Player configuration -The player also has a share button. It is advised that customers disable this in the [the JW Player Config](https://support.jwplayer.com/articles/how-to-implement-social-sharing) that is linked to the web-app config. +The player also has a share button. It is advised that customers disable this in the [the JW Player Config](https://docs.jwplayer.com/platform/docs/players-set-display-options-and-sharing#sharing) that is linked to the web-app config. ![Disable sharing in player](../_images/share-player.jpg) ## Deeplink to devices -In some cases opening a video URL on mobile device should open the native app rather than the web app. +In some cases opening a video URL on mobile device should open the native app rather than the web app. -This is not supported at this moment in web app. This requires logic to detect the device and route the user to the local app or the app store in case the app is not install yet. +This is not supported at this moment in web app. This requires logic to detect the device and route the user to the local app or the app store in case the app is not install yet. Services such as [brach.io](branch.io) and [Google Firebase Dynamic Links]([Firebase Dynamic Links | Deep link potential users to the right place inside your app](https://firebase.google.com/products/dynamic-links)) solve this problem. diff --git a/docs/frameworks.md b/docs/frameworks.md index 609783882..260b03b7b 100644 --- a/docs/frameworks.md +++ b/docs/frameworks.md @@ -2,7 +2,7 @@ ## Typescript -Typescript is superset of javascript, TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. +Typescript is a superset of Javascript, TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. - Optional static typing - Spot bugs at compile time diff --git a/docs/initialization-file.md b/docs/initialization-file.md index 30cb2a52e..2f56581c6 100644 --- a/docs/initialization-file.md +++ b/docs/initialization-file.md @@ -1,10 +1,10 @@ # Initialization (ini) File -The JW OTT Web App loads a small initialization (.ini) file at startup. This file provides a mechanism to set key startup parameters without modifying the source code. +The JW OTT Web App loads a small initialization (.ini) file at startup. This file provides a mechanism to set key startup parameters without modifying the source code. Template ini files are included in the repo and with the pre-compiled production release builds ([.webapp.prod.ini](/ini/templates/.webapp.prod.ini)). Make sure you include a copy of the ini file edited to include your account data at `/public/.webapp.ini` for the application to load correctly. -For all manual builds (`yarn start` or `yarn build`), the ini file is copied from `/ini/.webapp..ini` to `build/public/.webapp.ini`, which the application fetches and parses at startup. For production builds, the ini file is stripped of comments and extra whitespace. +For all manual builds (`yarn start` or `yarn build`), the ini file is copied from `/ini/.webapp..ini` to `build/public/.webapp.ini`, which the application fetches and parses at startup. For production builds, the ini file is stripped of comments and extra whitespace. If a file doesn't exist in /ini/.webapp..ini, then the template file will first be copied from [`/ini/templates`](/ini/templates). All of the .ini files directly inside of `/ini` are ignored in git, so you can create your own files locally to run the application with your account parameters without creating conflicts with committed code or leaking your details into source control. @@ -17,7 +17,7 @@ The 8 character ID (or the url path) of the app config from your JWP account tha This value can alternatively be provided at compile time via the [APP_DEFAULT_CONFIG_SOURCE](build-from-source.md#app_default_config_source) environment variable if you are doing your own builds. Keep in mind, if the `deafultConfigSource` ini setting is provided, it will be used even if the [APP_DEFAULT_CONFIG_SOURCE](build-from-source.md#app_default_config_source) environment variable is set. -> Note: you probably always want to include a default config source for any production deployment. If there are no valid config sources the application will throw an error at startup. +> Note: you probably always want to include a default config source for any production deployment. If there are no valid config sources the application will throw an error at startup. ### playerId @@ -51,6 +51,6 @@ See [.webapp.test.ini](/ini/templates/.webapp.test.ini) for an example. ### UNSAFE_allowAnyConfigSource -Boolean flag which if true, enables **ANY** 8-character app config ID (or path) to be specified with the [`app-config=` query param](configuration.md#switching-between-app-configs). +Boolean flag which if true, enables **ANY** 8-character app config ID (or path) to be specified with the [`app-config=` query param](configuration.md#switching-between-app-configs). ->***Warning:** Generally the `UNSAFE_allowAnyConfigSource` option should only be used for dev, test, or demo deployments, because it will allow anyone to create URL's that specify any config to be displayed on your domain.* +> _**Warning:** Generally the `UNSAFE_allowAnyConfigSource` option should only be used for dev, test, or demo deployments, because it will allow anyone to create URL's that specify any config to be displayed on your domain._ diff --git a/package.json b/package.json index 2464e697b..557a5023f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jw-ott-webapp", - "version": "4.6.2", + "version": "4.6.3", "main": "index.js", "repository": "https://github.com/jwplayer/ott-web-app.git", "author": "JW Player", @@ -39,6 +39,7 @@ "deploy:github": "node ./scripts/deploy-github.js" }, "dependencies": { + "@codeceptjs/allure-legacy": "^1.0.2", "@inplayer-org/inplayer.js": "^3.13.7", "classnames": "^2.3.1", "date-fns": "^2.28.0", diff --git a/test-e2e/codecept.desktop.js b/test-e2e/codecept.desktop.js index b9c217638..1c61faef8 100644 --- a/test-e2e/codecept.desktop.js +++ b/test-e2e/codecept.desktop.js @@ -16,8 +16,9 @@ exports.config = { Playwright: { url: 'http://localhost:8080', show: !!process.env.SHOW, - browser: 'chromium', + channel: 'chrome', locale: 'en-US', + keepCookies: false, }, }, include: { @@ -38,6 +39,7 @@ exports.config = { }, allure: { enabled: true, + require: '@codeceptjs/allure-legacy', }, }, }; diff --git a/test-e2e/codecept.mobile.js b/test-e2e/codecept.mobile.js index bca94f98a..f5e9e38e9 100644 --- a/test-e2e/codecept.mobile.js +++ b/test-e2e/codecept.mobile.js @@ -19,6 +19,7 @@ exports.config = { show: !!process.env.SHOW, channel: 'chrome', emulate: devices['Pixel 5'], + keepCookies: false, }, }, include: { @@ -39,6 +40,7 @@ exports.config = { }, allure: { enabled: true, + require: '@codeceptjs/allure-legacy', }, }, }; diff --git a/test-e2e/tests/watch_history/logged_in_test.ts b/test-e2e/tests/watch_history/logged_in_test.ts index 261b9e54d..7505cdc58 100644 --- a/test-e2e/tests/watch_history/logged_in_test.ts +++ b/test-e2e/tests/watch_history/logged_in_test.ts @@ -63,17 +63,18 @@ function runTestSuite(config: typeof testConfigs.svod, configNoWatchlist: typeof I.dontSee(constants.continueWatchingShelfTitle); await registerOrLogin(I); - I.see(constants.continueWatchingShelfTitle); - - const continueWatchingShelfXPath = makeShelfXpath(ShelfId.continueWatching); + I.clickHome(); + I.waitForText(constants.continueWatchingShelfTitle, normalTimeout); - await within(continueWatchingShelfXPath, async () => { + await within(makeShelfXpath(ShelfId.continueWatching), async () => { I.see(videoTitle); I.see('10 min'); }); - await I.openVideoCard(videoTitle, ShelfId.continueWatching, false, async (locator) => await checkProgress(I, locator, (80 / videoLength) * 100)); + const selector = `${makeShelfXpath(ShelfId.continueWatching)}//div[@aria-label="Play ${videoTitle}"]`; + await checkProgress(I, selector, (80 / videoLength) * 100); + I.click(selector); await I.waitForPlayerPlaying(videoTitle); await checkElapsed(I, 1, 20); diff --git a/test-e2e/utils/password_utils.ts b/test-e2e/utils/password_utils.ts index d13f24cfc..53c4ca5f1 100644 --- a/test-e2e/utils/password_utils.ts +++ b/test-e2e/utils/password_utils.ts @@ -12,41 +12,20 @@ async function testPasswordToggling(I: CodeceptJS.I, name = 'password') { I.fillField({ name }, 'password123!'); await checkPasswordType(I, name, 'password'); - // When the input type is password, you should not be able to copy the password value - await tryToCopyPassword(I, name, ''); I.click(`input[name="${name}"]+div div[aria-label="View password"]`); await checkPasswordType(I, name, 'text'); - // When the input type is text, you should be able to copy the password value - await tryToCopyPassword(I, name, 'password123!'); await I.writeClipboard('dummy'); I.click(`input[name="${name}"]+div div[aria-label="Hide password"]`); await checkPasswordType(I, name, 'password'); - - // Password should not be able to be copied again and whatever is in the clipboard should stay in the clipboard - await tryToCopyPassword(I, name, 'dummy'); } async function checkPasswordType(I: CodeceptJS.I, name, expectedType) { assert.strictEqual(await I.grabAttributeFrom(`input[name="${name}"]`, 'type'), expectedType); } -async function tryToCopyPassword(I: CodeceptJS.I, name, expectedResult) { - // Use Ctrl + A, Ctrl + C to highlight and copy the password - I.click(`input[name="${name}"]`); - - await I.pressKey(['CommandOrControl', 'A']); - await I.pressKey(['CommandOrControl', 'C']); - // For some reason keyboard copy doesn't work when running via yarn - await I.executeScript(() => document.execCommand('copy')); - - const clipboard = await I.readClipboard(); - - assert.strictEqual(clipboard, expectedResult); -} - export default { testPasswordToggling, createRandomEmail: function () { diff --git a/yarn.lock b/yarn.lock index 4c83ffa4e..c671ef609 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1143,6 +1143,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@codeceptjs/allure-legacy@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@codeceptjs/allure-legacy/-/allure-legacy-1.0.2.tgz#aec363916826be724ae72aa3031cacdd2cb08b27" + integrity sha512-YJX4ueJLaI01iLIqM1MPW3AHXYQ43KGMXFlN9ymgkn/4Dne6VgPI3I06fdJrnNV2rBN3rj9y0Bpa//bYSvfSLg== + dependencies: + allure-js-commons "^1.3.2" + "@codeceptjs/configure@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@codeceptjs/configure/-/configure-0.8.0.tgz#5eba9dae3cfe8f8fd0049d157aff1a793ddf93bf"