mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-06 05:01:13 -07:00
update lock
This commit is contained in:
commit
a6b11b33cd
51 changed files with 15314 additions and 18753 deletions
|
@ -43,8 +43,8 @@ jobs:
|
|||
- name: Run Docker Image
|
||||
run: nohup docker run --rm -p 5000:5000 ombi &
|
||||
|
||||
# - name: Run Wiremock Plex
|
||||
# run: nohup docker run -it --rm -p 32400:8080 --name wiremock wiremock/wiremock:2.35.0
|
||||
- name: Run Wiremock
|
||||
run: nohup docker run --rm -p 32400:8080 --name wiremock wiremock/wiremock:2.35.0 &
|
||||
|
||||
- name: Sleep for server to start
|
||||
run: sleep 20
|
||||
|
@ -61,7 +61,7 @@ jobs:
|
|||
# nohup dotnet run --project ./src/Ombi -- --host http://*:3577 &
|
||||
|
||||
- name: Cypress Tests
|
||||
uses: cypress-io/github-action@v2.8.2
|
||||
uses: cypress-io/github-action@v4
|
||||
with:
|
||||
record: true
|
||||
browser: chrome
|
||||
|
@ -73,3 +73,9 @@ jobs:
|
|||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Stop Docker
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -q | xargs -I {} docker logs {}
|
||||
docker container kill $(docker ps -q)
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -106,7 +106,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
dotnet-version: '6.0.x'
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
|
82
.github/workflows/chromatic.yml
vendored
82
.github/workflows/chromatic.yml
vendored
|
@ -1,47 +1,47 @@
|
|||
name: 'Chromatic'
|
||||
# name: 'Chromatic'
|
||||
|
||||
# Event for the workflow
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
# # Event for the workflow
|
||||
# on:
|
||||
# push:
|
||||
# workflow_dispatch:
|
||||
|
||||
# List of jobs
|
||||
jobs:
|
||||
storybook-build:
|
||||
# Operating System
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# # List of jobs
|
||||
# jobs:
|
||||
# storybook-build:
|
||||
# # Operating System
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v2
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
|
||||
- name: NodeModules Cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
# - name: NodeModules Cache
|
||||
# uses: actions/cache@v2
|
||||
# with:
|
||||
# path: '**/node_modules'
|
||||
# key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ./src/Ombi/ClientApp
|
||||
run: yarn
|
||||
# - name: Install dependencies
|
||||
# working-directory: ./src/Ombi/ClientApp
|
||||
# run: yarn
|
||||
|
||||
- name: Publish to Chromatic
|
||||
if: github.ref != 'refs/heads/master'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
projectToken: 7c47e1a1a4bd
|
||||
exitZeroOnChanges: true
|
||||
workingDir: ./src/Ombi/ClientApp
|
||||
buildScriptName: storybookbuild
|
||||
exitOnceUploaded: true
|
||||
# - name: Publish to Chromatic
|
||||
# if: github.ref != 'refs/heads/master'
|
||||
# uses: chromaui/action@v1
|
||||
# with:
|
||||
# projectToken: 7c47e1a1a4bd
|
||||
# exitZeroOnChanges: true
|
||||
# workingDir: ./src/Ombi/ClientApp
|
||||
# buildScriptName: storybookbuild
|
||||
# exitOnceUploaded: true
|
||||
|
||||
- name: Publish to Chromatic and auto accept changes
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
projectToken: 7c47e1a1a4bd
|
||||
autoAcceptChanges: true # 👈 Option to accept all changes
|
||||
workingDir: ./src/Ombi/ClientApp
|
||||
buildScriptName: storybookbuild
|
||||
exitOnceUploaded: true
|
||||
# - name: Publish to Chromatic and auto accept changes
|
||||
# if: github.ref == 'refs/heads/develop'
|
||||
# uses: chromaui/action@v1
|
||||
# with:
|
||||
# projectToken: 7c47e1a1a4bd
|
||||
# autoAcceptChanges: true # 👈 Option to accept all changes
|
||||
# workingDir: ./src/Ombi/ClientApp
|
||||
# buildScriptName: storybookbuild
|
||||
# exitOnceUploaded: true
|
||||
|
|
2
.github/workflows/pr.yml
vendored
2
.github/workflows/pr.yml
vendored
|
@ -33,7 +33,7 @@ jobs:
|
|||
|
||||
unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,3 +1,18 @@
|
|||
## [4.42.1](https://github.com/Ombi-app/Ombi/compare/v4.42.0...v4.42.1) (2023-06-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* More automation tests mainly around the Plex Settings page ([#4821](https://github.com/Ombi-app/Ombi/issues/4821)) ([21bfc5a](https://github.com/Ombi-app/Ombi/commit/21bfc5a45adf6da6a80854e19494a8ffdc9c0761))
|
||||
* src/Ombi.Notifications/Ombi.Notifications.csproj to reduce vulnerabilities ([#4969](https://github.com/Ombi-app/Ombi/issues/4969)) [skip ci] ([8584ad4](https://github.com/Ombi-app/Ombi/commit/8584ad46053c51f5da40b24f3efd1b9e5a031ddd))
|
||||
* upgrade @fortawesome/fontawesome-free from 6.1.2 to 6.4.0 ([#4965](https://github.com/Ombi-app/Ombi/issues/4965)) [skip ci] ([84454e5](https://github.com/Ombi-app/Ombi/commit/84454e53c00c808e8a393c7750bdc418a7593e91))
|
||||
* upgrade @microsoft/signalr from 6.0.11 to 6.0.16 ([#4964](https://github.com/Ombi-app/Ombi/issues/4964)) [skip ci] ([a0201e3](https://github.com/Ombi-app/Ombi/commit/a0201e3f585dc52f717e33c46ede35a4eccac736))
|
||||
* upgrade cypress-real-events from 1.7.4 to 1.8.1 ([#4968](https://github.com/Ombi-app/Ombi/issues/4968)) [skip ci] ([8a24b56](https://github.com/Ombi-app/Ombi/commit/8a24b56299c3bc98bf0d719ba448972aaa7f7461))
|
||||
* upgrade multiple dependencies with Snyk ([#4963](https://github.com/Ombi-app/Ombi/issues/4963)) [skip ci] ([6025c5e](https://github.com/Ombi-app/Ombi/commit/6025c5ed757438d3a5d79bd36fd789ef0297ce70))
|
||||
* upgrade primeng from 15.0.0-rc.1 to 15.4.1 ([#4962](https://github.com/Ombi-app/Ombi/issues/4962)) [skip ci] ([23a4fed](https://github.com/Ombi-app/Ombi/commit/23a4fede69898a25b342aed78a8cda553c1fd18d))
|
||||
|
||||
|
||||
|
||||
# [4.42.0](https://github.com/Ombi-app/Ombi/compare/v4.41.1...v4.42.0) (2023-06-02)
|
||||
|
||||
|
||||
|
@ -2432,12 +2447,3 @@
|
|||
|
||||
|
||||
|
||||
## [4.32.3](https://github.com/Ombi-app/Ombi/compare/v4.32.2...v4.32.3) (2022-11-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **sonarr:** V4 actually works this time around ([f62e70f](https://github.com/Ombi-app/Ombi/commit/f62e70fc493c7971da5e4508ce10522f5df0bbf7))
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ ____
|
|||
[](https://github.com/ombi-app/Ombi)
|
||||
[](http://www.firsttimersonly.com/)
|
||||
[](https://crowdin.com/project/ombi)
|
||||
[](https://github.com/Ombi-app/Ombi/actions/workflows/cypress.yml)
|
||||
[](https://github.com/Ombi-app/Ombi/actions/workflows/automation-tests.yml)
|
||||
|
||||
[](https://patreon.com/tidusjar/Ombi)
|
||||
[](https://paypal.me/PlexRequestsNet)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"></packagereference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<PackageReference Include="nunit" Version="3.13.3" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageReference Include="Quartz" Version="3.5.0" />
|
||||
<PackageReference Include="Quartz" Version="3.6.2" />
|
||||
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.15.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"></packagereference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="Moq.AutoMock" Version="3.4.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.15.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"></packagereference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Quartz" Version="3.5.0" />
|
||||
<PackageReference Include="Quartz" Version="3.6.2" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||
<PackageReference Include="System.Diagnostics.Process" Version="4.3.0" />
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<PackageReference Include="nunit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
<PackageReference Include="Quartz" Version="3.5.0" />
|
||||
<PackageReference Include="Quartz" Version="3.6.2" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<PackageReference Include="Moq" Version="4.18.2" />
|
||||
<PackageReference Include="MockQueryable.Moq" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<PackageReference Include="NUnit.ConsoleRunner" Version="3.15.2" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.3.2"></packagereference>
|
||||
<packagereference Include="Microsoft.NET.Test.Sdk" Version="17.6.2"></packagereference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
"angularx-qrcode": "^15.0.0",
|
||||
"bootstrap": "^4.2.1",
|
||||
"core-js": "^2.5.4",
|
||||
"jquery": "3.6.1",
|
||||
"jquery": "3.7.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
"ng2-cookies": "^1.0.12",
|
||||
|
@ -50,8 +50,7 @@
|
|||
"primeng": "^15.4.1",
|
||||
"rxjs": "^7.5.4",
|
||||
"ts-md5": "^1.2.7",
|
||||
"tslint-angular": "^1.1.2",
|
||||
"zone.js": "~0.11.4"
|
||||
"zone.js": "~0.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^15.0.2",
|
||||
|
|
|
@ -5,47 +5,47 @@
|
|||
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-label>Server Name</mat-label>
|
||||
<input matInput placeholder="Server Name" name="name" [(ngModel)]="this.data.server.name" value="{{this.data.server.name}}">
|
||||
<input matInput id="serverName" placeholder="Server Name" name="name" [(ngModel)]="this.data.server.name" value="{{this.data.server.name}}">
|
||||
</mat-form-field>
|
||||
|
||||
<div class="row">
|
||||
<mat-form-field class="col-md-6 col-12" appearance="outline" floatLabel=auto>
|
||||
<mat-label>Hostname / IP</mat-label>
|
||||
<input matInput placeholder="Hostname or IP" name="ip" [(ngModel)]="this.data.server.ip" value="{{this.data.server.ip}}"
|
||||
<input matInput id="ip" placeholder="Hostname or IP" name="ip" [(ngModel)]="this.data.server.ip" value="{{this.data.server.ip}}"
|
||||
#serverHostnameIpControl="ngModel" required>
|
||||
<mat-error *ngIf="serverHostnameIpControl.hasError('required')">Must be specified.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-md-4 col-7" appearance="outline" floatLabel=auto>
|
||||
<mat-label>Port</mat-label>
|
||||
<input matInput placeholder="Port" name="port" [(ngModel)]="this.data.server.port" value="{{this.data.server.port}}"
|
||||
<input id="port" matInput placeholder="Port" name="port" [(ngModel)]="this.data.server.port" value="{{this.data.server.port}}"
|
||||
#serverPortControl="ngModel" required pattern="^[0-9]*$">
|
||||
<mat-error *ngIf="serverPortControl.hasError('required')">Must be specified.</mat-error>
|
||||
<mat-error *ngIf="serverPortControl.hasError('pattern')">Must be a number.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-slide-toggle class="col-md-2 col-5 mt-3" id="ssl" name="ssl" [(ngModel)]="this.data.server.ssl" [checked]="this.data.server.ssl">
|
||||
<mat-slide-toggle id="ssl" class="col-md-2 col-5 mt-3" id="ssl" name="ssl" [(ngModel)]="this.data.server.ssl" [checked]="this.data.server.ssl">
|
||||
SSL
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-label>Plex Authorization Token</mat-label>
|
||||
<input matInput placeholder="Plex Authorization Token" name="authToken" [(ngModel)]="this.data.server.plexAuthToken" value="{{this.data.server.plexAuthToken}}"
|
||||
<input id="authToken" matInput placeholder="Plex Authorization Token" name="authToken" [(ngModel)]="this.data.server.plexAuthToken" value="{{this.data.server.plexAuthToken}}"
|
||||
#serverApiKeyControl="ngModel" required>
|
||||
<mat-error *ngIf="serverApiKeyControl.hasError('required')">Must be specified.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-label>Machine Identifier</mat-label>
|
||||
<input matInput placeholder="Machine Identifier" name="MachineIdentifier" [(ngModel)]="this.data.server.machineIdentifier" value="{{this.data.server.machineIdentifier}}"
|
||||
<input id="machineId" matInput placeholder="Machine Identifier" name="MachineIdentifier" [(ngModel)]="this.data.server.machineIdentifier" value="{{this.data.server.machineIdentifier}}"
|
||||
#serverApiKeyControl="ngModel" required>
|
||||
<mat-error *ngIf="serverApiKeyControl.hasError('required')">Must be specified.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-label>Externally Facing Hostname</mat-label>
|
||||
<input matInput placeholder="e.g. https://emby.this.data.server.com/" name="serverHostname" name="hostname"
|
||||
<input id="externalHostname" matInput placeholder="e.g. https://emby.this.data.server.com/" name="serverHostname" name="hostname"
|
||||
[(ngModel)]="this.data.server.serverHostname" value="{{this.data.server.serverHostname}}" >
|
||||
<mat-hint>
|
||||
This will be the external address that users will navigate to when they press the 'View On Plex' button
|
||||
|
@ -58,7 +58,7 @@
|
|||
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<mat-label>Episode Batch Size</mat-label>
|
||||
<input matInput placeholder="150" name="MachineIdentifier" [(ngModel)]="this.data.server.episodeBatchSize" value="{{this.data.server.episodeBatchSize}}">
|
||||
<input id="batchSize" matInput placeholder="150" name="MachineIdentifier" [(ngModel)]="this.data.server.episodeBatchSize" value="{{this.data.server.episodeBatchSize}}">
|
||||
<mat-hint>
|
||||
150 by default, you shouldn't need to change this, this sets how many episodes we request from Plex at a single time.
|
||||
</mat-hint>
|
||||
|
@ -66,7 +66,7 @@
|
|||
|
||||
<h2>Libraries</h2>
|
||||
<div>
|
||||
<button mat-raised-button (click)="loadLibraries()"
|
||||
<button id="loadLibs" mat-raised-button (click)="loadLibraries()"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Load Libraries
|
||||
<i class="fas fa-film"></i>
|
||||
</button>
|
||||
|
@ -74,10 +74,10 @@
|
|||
<div *ngIf="this.data.server.plexSelectedLibraries && this.data.server.plexSelectedLibraries.length > 0">
|
||||
<label>Please select the libraries for Ombi to monitor. If nothing is selected, Ombi will monitor all
|
||||
libraries.</label>
|
||||
<div *ngFor="let lib of this.data.server.plexSelectedLibraries">
|
||||
<div *ngFor="let lib of this.data.server.plexSelectedLibraries; let i = index">
|
||||
<div class="md-form-field">
|
||||
<div class="checkbox">
|
||||
<mat-slide-toggle [(ngModel)]="lib.enabled" [checked]="lib.enabled"
|
||||
<mat-slide-toggle id="lib-{{i}}" [(ngModel)]="lib.enabled" [checked]="lib.enabled"
|
||||
for="{{lib.title}}">{{lib.title}}</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -87,7 +87,7 @@
|
|||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align=end>
|
||||
<button style="margin: .5em 0 0 .5em;" align-middle mat-stroked-button color="accent"
|
||||
<button id="testPlexButton" style="margin: .5em 0 0 .5em;" align-middle mat-stroked-button color="accent"
|
||||
(click)="testPlex()">
|
||||
<span style="display: flex; align-items: baseline; white-space: pre-wrap;">
|
||||
<i class="fas fa-vial"></i>
|
||||
|
@ -95,7 +95,7 @@
|
|||
</span>
|
||||
</button>
|
||||
|
||||
<button style="margin: .5em 0 0 .5em;" align-middle mat-stroked-button color="warn"
|
||||
<button id="deleteServer" style="margin: .5em 0 0 .5em;" align-middle mat-stroked-button color="warn"
|
||||
(click)="delete()">
|
||||
<span style="display: flex; align-items: baseline; white-space: pre-wrap;">
|
||||
<i class="fas fa-trash"></i>
|
||||
|
@ -103,7 +103,7 @@
|
|||
</span>
|
||||
</button>
|
||||
|
||||
<button style="margin: .5em 0 0 0.5em;" mat-stroked-button color="basic" (click)="cancel()">
|
||||
<button id="cancel" style="margin: .5em 0 0 0.5em;" mat-stroked-button color="basic" (click)="cancel()">
|
||||
<span style="display: flex; align-items: baseline; white-space: pre-wrap;">
|
||||
<i class="fas fa-times"></i>
|
||||
<span> Cancel</span>
|
||||
|
@ -111,7 +111,7 @@
|
|||
</button>
|
||||
|
||||
|
||||
<button style="margin: .5em 0 0 .5em;" mat-stroked-button color="accent"
|
||||
<button id="saveServer" style="margin: .5em 0 0 .5em;" mat-stroked-button color="accent"
|
||||
(click)="save()">
|
||||
<span style="display: flex; align-items: baseline; white-space: pre-wrap;">
|
||||
<i style="vertical-align: text-top;" class="fas fa-check"></i>
|
||||
|
|
|
@ -37,7 +37,7 @@ export class PlexServerDialogComponent {
|
|||
public testPlex() {
|
||||
this.testerService.plexTest(this.data.server).pipe(take(1))
|
||||
.subscribe(x => {
|
||||
if (x === true) {
|
||||
if (x) {
|
||||
this.notificationService.success(`Successfully connected to the Plex server ${this.data.server.name}!`);
|
||||
} else {
|
||||
this.notificationService.error(`We could not connect to the Plex server ${this.data.server.name}!`);
|
||||
|
|
|
@ -30,13 +30,13 @@
|
|||
<h2 style="margin: 1em 0 0 0;">Servers</h2>
|
||||
<mat-list style="display:flex; flex-flow: wrap;">
|
||||
<mat-card class="server-card" *ngFor="let server of settings.servers">
|
||||
<button mat-button (click)="edit(server)">
|
||||
<button mat-button (click)="edit(server)" id="{{server.name}}-button">
|
||||
<h3>{{server.name}}</h3>
|
||||
</button>
|
||||
</mat-card>
|
||||
|
||||
<mat-card class="server-card new-server-card">
|
||||
<button mat-button (click)="newServer()">
|
||||
<button mat-button (click)="newServer()" id="newServer">
|
||||
<i class="fas fa-plus fa-xl"></i>
|
||||
<h3>Manually Add Server</h3>
|
||||
</button>
|
||||
|
@ -114,13 +114,13 @@
|
|||
<div class="md-form-field col-10">
|
||||
<div *ngIf="!loadedServers">
|
||||
<mat-form-field appearance="outline" floatLabel=auto>
|
||||
<input disabled matInput placeholder="No Servers Loaded" id="selectServer-noservers">
|
||||
<input disabled matInput placeholder="No Servers Loaded" id="servers">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loadedServers">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-select placeholder="Servers Loaded! Please Select">
|
||||
<mat-select placeholder="Servers Loaded! Please Select" id="servers">
|
||||
<mat-option (click)="selectServer(s)"
|
||||
*ngFor="let s of loadedServers.servers.server" [value]="s.server">
|
||||
{{s.name}}</mat-option>
|
||||
|
|
|
@ -86,8 +86,8 @@ export class UserPreferenceComponent implements OnInit {
|
|||
|
||||
public languageSelected() {
|
||||
this.identityService.updateLanguage(this.selectedLang).subscribe(_ => {
|
||||
this.translate.use(this.selectedLang).subscribe();
|
||||
this.notification.success(this.translate.instant("UserPreferences.Updated"))
|
||||
this.translate.use(this.selectedLang);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
"node_modules/codelyzer"
|
||||
],
|
||||
"extends": [
|
||||
"tslint:recommended",
|
||||
"tslint-angular"
|
||||
"tslint:recommended"
|
||||
],
|
||||
"rules": {
|
||||
"max-line-length": [
|
||||
|
|
File diff suppressed because it is too large
Load diff
45
tests/cypress.config.ts
Normal file
45
tests/cypress.config.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { defineConfig } from 'cypress';
|
||||
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
|
||||
import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-preprocessor";
|
||||
import createEsbuildPlugin from "@badeball/cypress-cucumber-preprocessor/esbuild";
|
||||
|
||||
export default defineConfig({
|
||||
watchForFileChanges: true,
|
||||
chromeWebSecurity: false,
|
||||
viewportWidth: 2560,
|
||||
viewportHeight: 1440,
|
||||
retries: {
|
||||
runMode: 2,
|
||||
openMode: 0,
|
||||
},
|
||||
env: {
|
||||
username: 'a',
|
||||
password: 'a',
|
||||
dockerhost: 'http://172.17.0.1'
|
||||
},
|
||||
projectId: 'o5451s',
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
async setupNodeEvents(
|
||||
on: Cypress.PluginEvents,
|
||||
config: Cypress.PluginConfigOptions
|
||||
): Promise<Cypress.PluginConfigOptions> {
|
||||
await addCucumberPreprocessorPlugin(on, config);
|
||||
|
||||
on(
|
||||
"file:preprocessor",
|
||||
createBundler({
|
||||
plugins: [createEsbuildPlugin(config)],
|
||||
})
|
||||
);
|
||||
|
||||
// Make sure to return the config object as it might have been modified by the plugin.
|
||||
return config;
|
||||
// return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
baseUrl: 'http://localhost:5000',
|
||||
specPattern: ['cypress/tests/**/*.spec.ts*', '**/*.feature'],
|
||||
excludeSpecPattern: ['**/snapshots/*'],
|
||||
},
|
||||
})
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"$schema": "https://on.cypress.io/cypress.schema.json",
|
||||
"supportFile": "cypress/support/index.ts",
|
||||
"baseUrl": "http://localhost:5000",
|
||||
"integrationFolder": "cypress/tests",
|
||||
"testFiles": "**/*.spec.ts*",
|
||||
"watchForFileChanges": true,
|
||||
"chromeWebSecurity": false,
|
||||
"viewportWidth": 2560,
|
||||
"viewportHeight": 1440,
|
||||
"retries": {
|
||||
"runMode": 2,
|
||||
"openMode": 0
|
||||
},
|
||||
"ignoreTestFiles": [
|
||||
"**/snapshots/*"
|
||||
],
|
||||
"env": {
|
||||
"username": "a",
|
||||
"password": "a"
|
||||
},
|
||||
"projectId": "o5451s"
|
||||
}
|
21
tests/cypress/features/01-wizard/wizard.feature
Normal file
21
tests/cypress/features/01-wizard/wizard.feature
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
Feature: Wizard Setup
|
||||
Scenario: When visiting Ombi for the first time we should be on the Wizard page
|
||||
When I visit Ombi
|
||||
Then I should be on the "Wizard"
|
||||
|
||||
Scenario: When navigating through the Wizard feature we are required to create a local user
|
||||
When I visit Ombi
|
||||
And I click through all of the pages
|
||||
And I finish the Wizard
|
||||
Then I should get a notification "Username '' is invalid, can only contain letters or digits."
|
||||
And I should be on the User tab
|
||||
|
||||
Scenario: Completing the Wizard
|
||||
When I visit Ombi
|
||||
And I click through to the user page
|
||||
And I enter a username
|
||||
And I enter a password
|
||||
And I go to the finished tab
|
||||
And I finish the Wizard
|
||||
Then I should be on the "login"
|
53
tests/cypress/features/01-wizard/wizard.ts
Normal file
53
tests/cypress/features/01-wizard/wizard.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { Given, When, Then } from "@badeball/cypress-cucumber-preprocessor";
|
||||
import { wizardPage as Page } from "@/integration/page-objects";
|
||||
|
||||
Given("I set the Landing Page to {string}", (bool) => {
|
||||
cy.landingSettings(bool);
|
||||
});
|
||||
|
||||
When("I visit Ombi", () => {
|
||||
Page.visit();
|
||||
});
|
||||
|
||||
When("I click through all of the pages", () => {
|
||||
Page.welcomeTab.next.click();
|
||||
Page.mediaServerTab.next.click();
|
||||
Page.localUserTab.next.click();
|
||||
Page.ombiConfigTab.next.click();
|
||||
});
|
||||
|
||||
When("I finish the Wizard", () => {
|
||||
Page.finishButton.click();
|
||||
});
|
||||
|
||||
When("I click through to the user page", () => {
|
||||
Page.welcomeTab.next.click();
|
||||
Page.mediaServerTab.next.click();
|
||||
});
|
||||
|
||||
When("I enter a username", () => {
|
||||
Page.localUserTab.username.type(Cypress.env("username"));
|
||||
});
|
||||
|
||||
When("I enter a password", () => {
|
||||
Page.localUserTab.password.type(Cypress.env("password"));
|
||||
});
|
||||
|
||||
When("I go to the finished tab", () => {
|
||||
Page.localUserTab.next.click();
|
||||
Page.ombiConfigTab.next.click();
|
||||
});
|
||||
|
||||
Then("I should be on the {string}", (string) => {
|
||||
cy.location("pathname").should("eq", `/${string}`);
|
||||
});
|
||||
|
||||
Then("I should get a notification {string}", (string) => {
|
||||
cy.verifyNotification(string);
|
||||
});
|
||||
|
||||
Then("I should be on the User tab", () => {
|
||||
Page.matStepsHeader.then((_) => {
|
||||
cy.get('#cdk-step-label-0-2').should('have.attr', 'aria-selected', 'true');
|
||||
});
|
||||
});
|
13
tests/cypress/features/login/login.feature
Normal file
13
tests/cypress/features/login/login.feature
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
Feature: Login Page
|
||||
Scenario: When visiting Ombi and the Landing Page is enabled, we should end up on the landing page
|
||||
Given I set the Landing Page to "true"
|
||||
When I visit Ombi
|
||||
Then I should be on the "landingpage"
|
||||
Then I click continue
|
||||
Then I should be on the "login/true"
|
||||
|
||||
Scenario: When visiting Ombi and the Landing Page is disabled, we should end up on the login page
|
||||
Given I set the Landing Page to "false"
|
||||
When I visit Ombi
|
||||
Then I should be on the "login"
|
19
tests/cypress/features/login/login.ts
Normal file
19
tests/cypress/features/login/login.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { After, Before, Given, When, Then } from "@badeball/cypress-cucumber-preprocessor";
|
||||
import { loginPage as Page } from "@/integration/page-objects";
|
||||
|
||||
Given("I set the Landing Page to {string}", (bool) => {
|
||||
cy.landingSettings(bool);
|
||||
});
|
||||
|
||||
When("I visit Ombi", () => {
|
||||
Page.visit();
|
||||
});
|
||||
|
||||
Then("I should be on the {string}", (string) => {
|
||||
cy.location("pathname").should("eq", `/${string}`);
|
||||
|
||||
});
|
||||
|
||||
Then("I click continue", () => {
|
||||
cy.get("[data-cy=continue]").click();
|
||||
});
|
23
tests/cypress/fixtures/mocks/plex/plex-libraries.mock.json
Normal file
23
tests/cypress/fixtures/mocks/plex/plex-libraries.mock.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"urlPattern": "/library/sections"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"jsonBody": {
|
||||
"mediaContainer": {
|
||||
"directory":[
|
||||
{ "key": "1", "title": "lib1"},
|
||||
{ "key": "2", "title": "lib2"},
|
||||
{ "key": "3", "title": "lib3"},
|
||||
{ "key": "4", "title": "lib4"},
|
||||
{ "key": "5", "title": "lib5"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
16
tests/cypress/fixtures/mocks/plex/plex-test.mock.json
Normal file
16
tests/cypress/fixtures/mocks/plex/plex-test.mock.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"request": {
|
||||
"method": "GET"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"jsonBody": {
|
||||
"mediaContainer": {
|
||||
"version": "99"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,8 +75,8 @@ class TvDetailsPage extends BasePage {
|
|||
return cy.get('#partiallyAvailableBtn');
|
||||
}
|
||||
|
||||
get reportIssueButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#reportIssueBtn');
|
||||
reportIssueButton(timeout: number): Cypress.Chainable<any> {
|
||||
return cy.get('#reportIssueBtn', { timeout: timeout});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,3 +6,5 @@ export * from './search/search.page';
|
|||
export * from './user-preferences/user-preferences.page';
|
||||
export * from './requests/requests.page';
|
||||
export * from './details/movies/moviedetails.page';
|
||||
export * from './settings/settings.page';
|
||||
export * from './settings/plex/plex-settings.page';
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
import { BasePage } from "../../base.page";
|
||||
|
||||
class PlexCredentials {
|
||||
get username(): Cypress.Chainable<any> {
|
||||
return cy.get('#username');
|
||||
}
|
||||
|
||||
get password(): Cypress.Chainable<any> {
|
||||
return cy.get('#password');
|
||||
}
|
||||
|
||||
get loadServers(): Cypress.Chainable<any> {
|
||||
return cy.get('#loadServers');
|
||||
}
|
||||
|
||||
get serverDropdown(): Cypress.Chainable<any> {
|
||||
return cy.get('#servers');
|
||||
}
|
||||
}
|
||||
|
||||
class PlexServerModal {
|
||||
get serverName(): Cypress.Chainable<any> {
|
||||
return cy.get('#serverName');
|
||||
}
|
||||
get hostName(): Cypress.Chainable<any> {
|
||||
return cy.get('#ip');
|
||||
}
|
||||
get port(): Cypress.Chainable<any> {
|
||||
return cy.get('#port');
|
||||
}
|
||||
get ssl(): Cypress.Chainable<any> {
|
||||
return cy.get('#ssl');
|
||||
}
|
||||
get authToken(): Cypress.Chainable<any> {
|
||||
return cy.get('#authToken');
|
||||
}
|
||||
get machineIdentifier(): Cypress.Chainable<any> {
|
||||
return cy.get('#machineId');
|
||||
}
|
||||
get externalHostname(): Cypress.Chainable<any> {
|
||||
return cy.get('#externalHostname');
|
||||
}
|
||||
get batchSize(): Cypress.Chainable<any> {
|
||||
return cy.get('#batchSize');
|
||||
}
|
||||
get loadLibraries(): Cypress.Chainable<any> {
|
||||
return cy.get('#loadLibs');
|
||||
}
|
||||
get testButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#testPlexButton');
|
||||
}
|
||||
get deleteButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#deleteServer');
|
||||
}
|
||||
get cancelButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#cancel');
|
||||
}
|
||||
get saveButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#saveServer');
|
||||
}
|
||||
|
||||
getLib(index: number): Cypress.Chainable<any> {
|
||||
return cy.get(`#lib-${index}`);
|
||||
}
|
||||
}
|
||||
|
||||
class PlexServersGrid {
|
||||
serverCardButton(name: string): Cypress.Chainable<any> {
|
||||
return cy.get(`#${name}-button`);
|
||||
}
|
||||
|
||||
get newServerButton(): Cypress.Chainable<any> {
|
||||
return cy.get('#newServer');
|
||||
}
|
||||
}
|
||||
|
||||
class PlexSettingsPage extends BasePage {
|
||||
|
||||
|
||||
get enableCheckbox(): Cypress.Chainable<any> {
|
||||
return cy.get('#enable');
|
||||
}
|
||||
|
||||
get enableWatchlist(): Cypress.Chainable<any> {
|
||||
return cy.get('#enableWatchlistImport');
|
||||
}
|
||||
|
||||
get submit(): Cypress.Chainable<any> {
|
||||
return cy.get('#save');
|
||||
}
|
||||
|
||||
get fullySync(): Cypress.Chainable<any> {
|
||||
return cy.get('#fullSync');
|
||||
}
|
||||
|
||||
get partialSync(): Cypress.Chainable<any> {
|
||||
return cy.get('#recentlyAddedSync');
|
||||
}
|
||||
|
||||
get clearAndResync(): Cypress.Chainable<any> {
|
||||
return cy.get('#clearData');
|
||||
}
|
||||
|
||||
get runWatchlist(): Cypress.Chainable<any> {
|
||||
return cy.get('#watchlistImport');
|
||||
}
|
||||
|
||||
plexCredentials = new PlexCredentials();
|
||||
plexServerModal = new PlexServerModal();
|
||||
plexServerGrid = new PlexServersGrid();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
visit(options: Cypress.VisitOptions): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id: string): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id: string, options: Cypress.VisitOptions): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id?: any, options?: any) {
|
||||
return cy.visit(`/Settings/Plex`, options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const plexSettingsPage = new PlexSettingsPage();
|
|
@ -0,0 +1,20 @@
|
|||
import { BasePage } from "../base.page";
|
||||
|
||||
|
||||
class SettingsPage extends BasePage {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
visit(options: Cypress.VisitOptions): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id: string): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id: string, options: Cypress.VisitOptions): Cypress.Chainable<Cypress.AUTWindow>;
|
||||
visit(id?: any, options?: any) {
|
||||
return cy.visit(`/Settings/About`, options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const settingsPage = new SettingsPage();
|
|
@ -12,10 +12,10 @@
|
|||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @type {Cypress.PluginConfig}
|
||||
*/
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ Cypress.Commands.add("getByData", (selector) => {
|
|||
if (element.fireEvent) {
|
||||
element.fireEvent('on' + event);
|
||||
} else {
|
||||
var evObj = document.createEvent('Events');
|
||||
const evObj = document.createEvent('Events');
|
||||
|
||||
evObj.initEvent(event, true, false);
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
// Import commands.js using ES2015 syntax:
|
||||
import './commands'
|
||||
import './request.commands';
|
||||
import './plex-settings.commands';
|
||||
import './mock-data.commands';
|
||||
import "cypress-real-events/support";
|
||||
import '@bahmutov/cy-api/support';
|
||||
|
15
tests/cypress/support/mock-data.commands.ts
Normal file
15
tests/cypress/support/mock-data.commands.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
Cypress.Commands.add('addMock', (mapping) => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: 'http://localhost:32400/__admin/mappings',
|
||||
body: mapping
|
||||
})
|
||||
})
|
||||
|
||||
Cypress.Commands.add('clearMocks', () => {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: 'http://localhost:32400/__admin/mappings'
|
||||
})
|
||||
})
|
12
tests/cypress/support/plex-settings.commands.ts
Normal file
12
tests/cypress/support/plex-settings.commands.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
Cypress.Commands.add('clearPlexServers', () => {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/v1/Settings/Plex/',
|
||||
body: `{"enable":false,"enableWatchlistImport":false,"monitorAll":false,"installId":"0c5c597d-56ea-4f34-8f59-18d34ec82482","servers":[],"id":2}`,
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + window.localStorage.getItem('id_token'),
|
||||
'Content-Type':"application/json"
|
||||
}
|
||||
})
|
||||
})
|
|
@ -1,47 +0,0 @@
|
|||
import { wizardPage as Page } from "@/integration/page-objects";
|
||||
|
||||
describe("Wizard Setup", () => {
|
||||
|
||||
it("Wizard should be first page", () => {
|
||||
Page.visit();
|
||||
cy.location("pathname").should("contains", "/Wizard");
|
||||
});
|
||||
|
||||
|
||||
it("Finsh with no local user", () => {
|
||||
Page.visit();
|
||||
|
||||
Page.welcomeTab.next.click();
|
||||
Page.mediaServerTab.next.click();
|
||||
Page.localUserTab.next.click();
|
||||
Page.ombiConfigTab.next.click();
|
||||
Page.finishButton.click();
|
||||
|
||||
cy.verifyNotification("Username '' is invalid, can only contain letters or digits.")
|
||||
|
||||
// Verify we end back up on the user page
|
||||
Page.matStepsHeader.then((items) => {
|
||||
|
||||
cy.get('#cdk-step-label-0-2').should('have.attr', 'aria-selected', 'true');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("Compete Wizard", () => {
|
||||
Page.visit();
|
||||
|
||||
Page.welcomeTab.next.click();
|
||||
Page.mediaServerTab.next.click();
|
||||
|
||||
Page.localUserTab.username.type(Cypress.env("username"));
|
||||
Page.localUserTab.password.type(Cypress.env("password"));
|
||||
|
||||
Page.localUserTab.next.click();
|
||||
Page.ombiConfigTab.next.click();
|
||||
|
||||
Page.finishButton.click();
|
||||
|
||||
cy.location("pathname").should("contains", "/login");
|
||||
});
|
||||
});
|
|
@ -67,16 +67,13 @@ describe("TV Details Buttons", () => {
|
|||
});
|
||||
|
||||
|
||||
it("Issues Enabled", () => {
|
||||
it.only("Issues Enabled", () => {
|
||||
cy.intercept("GET", "**/Settings/issuesenabled", 'true').as('issuesEnabled');
|
||||
|
||||
cy.visit("/details/tv/1399");
|
||||
|
||||
cy.wait('@issuesEnabled');
|
||||
cy.waitUntil(() => {
|
||||
return Page.reportIssueButton.should("be.visible");
|
||||
});
|
||||
Page.reportIssueButton.should('be.visible');
|
||||
Page.reportIssueButton(10000).should('be.visible');
|
||||
});
|
||||
|
||||
it("Issues Disabled", () => {
|
||||
|
@ -84,6 +81,6 @@ describe("TV Details Buttons", () => {
|
|||
|
||||
Page.visit("1399");
|
||||
|
||||
Page.reportIssueButton.should('not.exist');
|
||||
Page.reportIssueButton(1000).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,6 +17,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
movie.requested = false;
|
||||
|
||||
body[0] = movie;
|
||||
console.log('sending res')
|
||||
res.send(body);
|
||||
});
|
||||
}).as("cardsResponse");
|
||||
|
@ -24,7 +25,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body;
|
||||
var expectedId = body[0].id;
|
||||
var title = body[0].title;
|
||||
|
||||
|
@ -76,7 +77,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[6].id;
|
||||
var title = body[6].title;
|
||||
|
||||
|
@ -119,7 +120,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[1].id;
|
||||
var title = body[1].title;
|
||||
|
||||
|
@ -151,7 +152,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[1].id;
|
||||
var title = body[1].title;
|
||||
|
||||
|
@ -183,7 +184,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[1].id;
|
||||
var title = body[1].title;
|
||||
|
||||
|
@ -220,7 +221,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
Page.visit();
|
||||
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[1].id;
|
||||
var title = body[1].title;
|
||||
|
||||
|
@ -284,7 +285,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
|
||||
cy.wait("@otherResponses");
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[3].id;
|
||||
var title = body[3].title;
|
||||
|
||||
|
@ -337,7 +338,7 @@ describe("Discover Cards Requests Tests", () => {
|
|||
|
||||
cy.wait("@otherResponses");
|
||||
cy.wait("@cardsResponse").then((res) => {
|
||||
const body = JSON.parse(res.response.body);
|
||||
const body = res.response.body
|
||||
var expectedId = body[5].id;
|
||||
var title = body[5].title;
|
||||
|
||||
|
|
|
@ -1,32 +1,22 @@
|
|||
import { loginPage as Page } from "@/integration/page-objects";
|
||||
|
||||
describe("Login Tests", () => {
|
||||
it("Landing Page is enabled, should redirect", () => {
|
||||
cy.landingSettings(true);
|
||||
Page.visit();
|
||||
cy.location("pathname").should("eq", "/landingpage");
|
||||
cy.get("[data-cy=continue]").click();
|
||||
cy.location("pathname").should("contains", "/login");
|
||||
});
|
||||
|
||||
it("Landing Page is disabled, should not redirect", () => {
|
||||
cy.landingSettings(false);
|
||||
Page.visit();
|
||||
|
||||
cy.location("pathname").should("eq", "/login");
|
||||
});
|
||||
|
||||
it("Plex OAuth Enabled, should be button", () => {
|
||||
cy.landingSettings(false);
|
||||
cy.fixture("login/authenticationSettngs").then((settings) => {
|
||||
settings.enableOAuth = true;
|
||||
cy.intercept("GET", "/Settings/Authentication", settings).as(
|
||||
cy.intercept("GET", "api/v1/Settings/Authentication", (req) => {
|
||||
req.reply((res) => {
|
||||
res.send(settings);
|
||||
});
|
||||
}).as(
|
||||
"authSettings"
|
||||
);
|
||||
});
|
||||
|
||||
Page.visit();
|
||||
|
||||
cy.wait("@authSettings");
|
||||
Page.plexSignInButton.should("be.visible");
|
||||
Page.ombiSignInButton.should("be.visible");
|
||||
});
|
||||
|
@ -35,7 +25,7 @@ describe("Login Tests", () => {
|
|||
cy.landingSettings(false);
|
||||
cy.fixture("login/authenticationSettngs").then((settings) => {
|
||||
settings.enableOAuth = false;
|
||||
cy.intercept("GET", "/Settings/Authentication", settings).as(
|
||||
cy.intercept("GET", "api/v1//Settings/Authentication", settings).as(
|
||||
"authSettings"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -24,7 +24,7 @@ describe("Navigation Bar Tests", () => {
|
|||
cy.removeLogin();
|
||||
cy.loginWithCreds(id, "a");
|
||||
|
||||
cy.intercept("GET", "search/Movie/Popular").as("discoverLoad");
|
||||
cy.intercept("GET", "api/v2/search/Movie/Popular/**").as("discoverLoad");
|
||||
Page.visit();
|
||||
|
||||
cy.wait("@discoverLoad");
|
||||
|
|
182
tests/cypress/tests/settings/plex/plex-settings.spec.ts
Normal file
182
tests/cypress/tests/settings/plex/plex-settings.spec.ts
Normal file
|
@ -0,0 +1,182 @@
|
|||
import { plexSettingsPage as Page } from "@/integration/page-objects";
|
||||
|
||||
describe("Plex Settings Tests", () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.clearPlexServers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cy.clearMocks();
|
||||
})
|
||||
|
||||
const plexTvApiResponse = `{
|
||||
"success": true,
|
||||
"message": null,
|
||||
"servers": {
|
||||
"server": [
|
||||
{
|
||||
"accessToken": "myaccessToken",
|
||||
"name": "AutomationServer",
|
||||
"address": "1.1.1.1",
|
||||
"port": "32400",
|
||||
"version": "1.30.0.6442-5070ad484",
|
||||
"scheme": "http",
|
||||
"host": "2.2.2.2",
|
||||
"localAddresses": "${Cypress.env("dockerhost")}",
|
||||
"machineIdentifier": "9999999999999999",
|
||||
"createdAt": "5555555555",
|
||||
"updatedAt": "6666666666",
|
||||
"owned": "1",
|
||||
"synced": "0",
|
||||
"sourceTitle": null,
|
||||
"ownerId": null,
|
||||
"home": null
|
||||
}
|
||||
],
|
||||
"friendlyName": "myPlex",
|
||||
"identifier": "com.plexapp.plugins.myplex",
|
||||
"machineIdentifier": "3dd86546546546540ff065465460c2654654654654",
|
||||
"size": "1"
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
it("Load Servers from Plex.TV Api and Save", () => {
|
||||
loadServerFromPlexTvApi();
|
||||
|
||||
const modal = Page.plexServerModal;
|
||||
modal.serverName.should('have.value','AutomationServer');
|
||||
modal.hostName.should('have.value', Cypress.env("dockerhost"));
|
||||
modal.port.should('have.value','32400');
|
||||
modal.authToken.should('have.value','myaccessToken');
|
||||
modal.machineIdentifier.should('have.value','9999999999999999');
|
||||
|
||||
modal.saveButton.click();
|
||||
|
||||
Page.plexServerGrid.serverCardButton('AutomationServer').should('be.visible');
|
||||
|
||||
Page.submit.click();
|
||||
|
||||
cy.wait("@plexSave");
|
||||
|
||||
});
|
||||
|
||||
it("Load Servers from Plex.TV Api and Edit", () => {
|
||||
loadServerFromPlexTvApi();
|
||||
|
||||
const modal = Page.plexServerModal;
|
||||
modal.saveButton.click();
|
||||
|
||||
Page.plexServerGrid.serverCardButton('AutomationServer').should('be.visible');
|
||||
|
||||
Page.submit.click();
|
||||
|
||||
cy.wait("@plexSave");
|
||||
|
||||
// Edit server
|
||||
Page.plexServerGrid.serverCardButton('AutomationServer').click();
|
||||
modal.serverName.should('have.value','AutomationServer');
|
||||
modal.hostName.should('have.value', Cypress.env("dockerhost"));
|
||||
modal.port.should('have.value','32400');
|
||||
modal.authToken.should('have.value','myaccessToken');
|
||||
modal.machineIdentifier.should('have.value','9999999999999999');
|
||||
|
||||
});
|
||||
|
||||
it("Load Servers from Plex.TV Api and Test", () => {
|
||||
cy.fixture('/mocks/plex/plex-test.mock').then((json) => {
|
||||
cy.addMock(json);
|
||||
});
|
||||
loadServerFromPlexTvApi();
|
||||
cy.intercept("POST", "api/v1/tester/plex", (req) => {
|
||||
req.reply((res) => {
|
||||
res.send(plexTvApiResponse);
|
||||
});
|
||||
}).as("testResponse");
|
||||
|
||||
const modal = Page.plexServerModal;
|
||||
|
||||
modal.testButton.click();
|
||||
cy.wait("@testResponse").then(() => {
|
||||
cy.contains("Successfully connected to the Plex server AutomationServer");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("Load Libraries from New Server", () => {
|
||||
cy.fixture('/mocks/plex/plex-libraries.mock').then((json) => {
|
||||
cy.addMock(json);
|
||||
});
|
||||
cy.intercept("POST", "api/v1/Plex/Libraries").as("libRequest");
|
||||
newServer();
|
||||
|
||||
const modal = Page.plexServerModal;
|
||||
modal.loadLibraries.click();
|
||||
|
||||
cy.wait("@libRequest");
|
||||
|
||||
modal.getLib(0).click();
|
||||
modal.getLib(0).should('contain.text',"lib1");
|
||||
});
|
||||
|
||||
it("Remove server", () => {
|
||||
loadServerFromPlexTvApi();
|
||||
const modal = Page.plexServerModal;
|
||||
modal.saveButton.click();
|
||||
|
||||
newServer(false);
|
||||
modal.saveButton.click();
|
||||
|
||||
Page.plexServerGrid.serverCardButton('AutomationServer').click();
|
||||
modal.deleteButton.click();
|
||||
Page.plexServerGrid.serverCardButton('ManualServer').click();
|
||||
modal.deleteButton.click();
|
||||
|
||||
Page.plexServerGrid.serverCardButton('AutomationServer').should('not.exist');
|
||||
Page.plexServerGrid.serverCardButton('ManualServer').should('not.exist');
|
||||
});
|
||||
|
||||
function loadServerFromPlexTvApi(visitPage = true) {
|
||||
cy.intercept("POST", "api/v1/Plex/servers", (req) => {
|
||||
req.reply((res) => {
|
||||
res.send(plexTvApiResponse);
|
||||
});
|
||||
}).as("serverResponse");
|
||||
|
||||
cy.intercept("POST", "api/v1/Settings/Plex").as('plexSave');
|
||||
|
||||
if (visitPage) {
|
||||
Page.visit();
|
||||
}
|
||||
|
||||
Page.plexCredentials.username.type('username');
|
||||
Page.plexCredentials.password.type('password');
|
||||
|
||||
Page.plexCredentials.loadServers.click();
|
||||
|
||||
cy.wait("@serverResponse");
|
||||
|
||||
Page.plexCredentials.serverDropdown.click().get('mat-option').contains('AutomationServer').click();
|
||||
}
|
||||
|
||||
function newServer(visitPage = true) {
|
||||
if (visitPage) {
|
||||
Page.visit();
|
||||
}
|
||||
|
||||
Page.plexServerGrid.newServerButton.click();
|
||||
const modal = Page.plexServerModal;
|
||||
|
||||
const server = JSON.parse(plexTvApiResponse);
|
||||
modal.serverName.clear();
|
||||
modal.serverName.type("ManualServer");
|
||||
modal.hostName.type(server.servers.server[0].localAddresses);
|
||||
modal.port.type(server.servers.server[0].port);
|
||||
modal.authToken.type(server.servers.server[0].accessToken);
|
||||
modal.machineIdentifier.type(server.servers.server[0].machineIdentifier);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
|
@ -12,12 +12,13 @@ const langs = [
|
|||
];
|
||||
|
||||
langs.forEach((l) => {
|
||||
it.only(`Change language to ${l.code}, UI should update`, () => {
|
||||
it.skip(`Change language to ${l.code}, UI should update`, () => {
|
||||
cy.intercept('POST','**/language').as('langSave');
|
||||
Page.visit();
|
||||
|
||||
Page.profile.languageSelectBox.click();
|
||||
Page.profile.languageSelectBoxOption(l.code).click();
|
||||
cy.wait(2000); // wait for UI to update
|
||||
Page.navbar.discover.contains(l.discover);
|
||||
|
||||
cy.wait('@langSave').then((intercept) => {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@badeball/cypress-cucumber-preprocessor": "^14.0.0",
|
||||
"@bahmutov/cy-api": "^1.5.0",
|
||||
"cypress": "6.8.0",
|
||||
"@bahmutov/cypress-esbuild-preprocessor": "^2.1.5",
|
||||
"cypress": "12.14.0",
|
||||
"cypress-wait-until": "^1.7.1",
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
|
@ -17,7 +19,7 @@
|
|||
"scripts": {
|
||||
"cypress:version": "cypress version",
|
||||
"cypress:verify": "cypress verify",
|
||||
"cypress:open": "cypress open",
|
||||
"cypress:open": "cypress open --config baseUrl=http://localhost:3577 --env dockerhost=http://localhost",
|
||||
"cypress:run": "cypress run",
|
||||
"types": "tsc --noEmit",
|
||||
"e2e": "cypress run",
|
||||
|
@ -25,6 +27,6 @@
|
|||
"demo:open": "cypress open --config-file cypress/config/demo.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"cypress-real-events": "^1.3.0"
|
||||
"cypress-real-events": "^1.8.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"target": "es6",
|
||||
"esModuleInterop": true,
|
||||
"lib": ["es2018", "dom"],
|
||||
"types": ["cypress", "cypress-wait-until", "cypress-image-snapshot", "cypress-real-events", "@bahmutov/cy-api"],
|
||||
"types": ["cypress", "cypress-wait-until", "cypress-image-snapshot", "cypress-real-events", "@bahmutov/cy-api", "node"],
|
||||
"baseUrl": "./cypress",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
|
|
1220
tests/yarn.lock
1220
tests/yarn.lock
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"version": "4.42.0"
|
||||
"version": "4.42.1"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue