diff --git a/jam-ui/.gitignore b/jam-ui/.gitignore index 86ea06c57..785f5ac36 100644 --- a/jam-ui/.gitignore +++ b/jam-ui/.gitignore @@ -27,3 +27,4 @@ yarn-error.log* /.idea /.vscode +/test-results \ No newline at end of file diff --git a/jam-ui/cypress/fixtures/example.json b/jam-ui/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/jam-ui/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/jam-ui/cypress/fixtures/notifications.json b/jam-ui/cypress/fixtures/notifications.json new file mode 100644 index 000000000..cb714ac74 --- /dev/null +++ b/jam-ui/cypress/fixtures/notifications.json @@ -0,0 +1,74 @@ +[ + { + "description": "TEXT_MESSAGE", + "source_user_id": "27bd4a30-d1b8-4eea-8454-01a104d59381", + "target_user_id": "a09f9a7e-afb7-489d-870d-e13a336e0b97", + "session_id": null, + "recording_id": null, + "invitation_id": null, + "join_request_id": null, + "friend_request_id": null, + "band_id": null, + "band_invitation_id": null, + "formatted_msg": "TEXT_MESSAGE", + "message": "Hello", + "created_at": "2021-10-07T00:09:57.704Z", + "lesson_session_id": null, + "purpose": null, + "source_user": { + "name": "Nuwan Chaturanga" + }, + "notification_id": "63fcd878-9a22-4419-9cee-8a51a615da97", + "fan_access": null, + "musician_access": null, + "approval_required": null + }, + { + "description": "FRIEND_REQUEST", + "source_user_id": "a09f9a7e-afb7-489d-870d-e13a336e0b97", + "target_user_id": "b1ddadd0-0263-47c4-bf91-e7767f386970", + "session_id": null, + "recording_id": null, + "invitation_id": null, + "join_request_id": null, + "friend_request_id": "7c842904-24f5-4515-8886-0c3d25ee641b", + "band_id": null, + "band_invitation_id": null, + "formatted_msg": "Seth Call has sent you a friend request.", + "message": null, + "created_at": "2021-10-15T05:36:48.527Z", + "lesson_session_id": null, + "purpose": null, + "source_user": { + "name": "Seth Call" + }, + "notification_id": "3364b5f1-8946-46a3-b635-86d89d237849", + "fan_access": null, + "musician_access": null, + "approval_required": null + }, + { + "description": "FRIEND_REQUEST_ACCEPTED", + "source_user_id": "29becbf4-8be5-4078-9405-0edadc9fa42d", + "target_user_id": "b1ddadd0-0263-47c4-bf91-e7767f386970", + "session_id": null, + "recording_id": null, + "invitation_id": null, + "join_request_id": null, + "friend_request_id": null, + "band_id": null, + "band_invitation_id": null, + "formatted_msg": "Peter Walker has accepted your friend request.", + "message": null, + "created_at": "2021-10-05T12:38:53.134Z", + "lesson_session_id": null, + "purpose": null, + "source_user": { + "name": "Peter Walker" + }, + "notification_id": "bb9269f3-721c-48cd-9bf6-bcff72877198", + "fan_access": null, + "musician_access": null, + "approval_required": null + } +] \ No newline at end of file diff --git a/jam-ui/cypress/fixtures/profile.json b/jam-ui/cypress/fixtures/profile.json deleted file mode 100644 index b6c355ca5..000000000 --- a/jam-ui/cypress/fixtures/profile.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": 8739, - "name": "Jane", - "email": "jane@example.com" -} \ No newline at end of file diff --git a/jam-ui/cypress/fixtures/users.json b/jam-ui/cypress/fixtures/users.json deleted file mode 100644 index 79b699aa7..000000000 --- a/jam-ui/cypress/fixtures/users.json +++ /dev/null @@ -1,232 +0,0 @@ -[ - { - "id": 1, - "name": "Leanne Graham", - "username": "Bret", - "email": "Sincere@april.biz", - "address": { - "street": "Kulas Light", - "suite": "Apt. 556", - "city": "Gwenborough", - "zipcode": "92998-3874", - "geo": { - "lat": "-37.3159", - "lng": "81.1496" - } - }, - "phone": "1-770-736-8031 x56442", - "website": "hildegard.org", - "company": { - "name": "Romaguera-Crona", - "catchPhrase": "Multi-layered client-server neural-net", - "bs": "harness real-time e-markets" - } - }, - { - "id": 2, - "name": "Ervin Howell", - "username": "Antonette", - "email": "Shanna@melissa.tv", - "address": { - "street": "Victor Plains", - "suite": "Suite 879", - "city": "Wisokyburgh", - "zipcode": "90566-7771", - "geo": { - "lat": "-43.9509", - "lng": "-34.4618" - } - }, - "phone": "010-692-6593 x09125", - "website": "anastasia.net", - "company": { - "name": "Deckow-Crist", - "catchPhrase": "Proactive didactic contingency", - "bs": "synergize scalable supply-chains" - } - }, - { - "id": 3, - "name": "Clementine Bauch", - "username": "Samantha", - "email": "Nathan@yesenia.net", - "address": { - "street": "Douglas Extension", - "suite": "Suite 847", - "city": "McKenziehaven", - "zipcode": "59590-4157", - "geo": { - "lat": "-68.6102", - "lng": "-47.0653" - } - }, - "phone": "1-463-123-4447", - "website": "ramiro.info", - "company": { - "name": "Romaguera-Jacobson", - "catchPhrase": "Face to face bifurcated interface", - "bs": "e-enable strategic applications" - } - }, - { - "id": 4, - "name": "Patricia Lebsack", - "username": "Karianne", - "email": "Julianne.OConner@kory.org", - "address": { - "street": "Hoeger Mall", - "suite": "Apt. 692", - "city": "South Elvis", - "zipcode": "53919-4257", - "geo": { - "lat": "29.4572", - "lng": "-164.2990" - } - }, - "phone": "493-170-9623 x156", - "website": "kale.biz", - "company": { - "name": "Robel-Corkery", - "catchPhrase": "Multi-tiered zero tolerance productivity", - "bs": "transition cutting-edge web services" - } - }, - { - "id": 5, - "name": "Chelsey Dietrich", - "username": "Kamren", - "email": "Lucio_Hettinger@annie.ca", - "address": { - "street": "Skiles Walks", - "suite": "Suite 351", - "city": "Roscoeview", - "zipcode": "33263", - "geo": { - "lat": "-31.8129", - "lng": "62.5342" - } - }, - "phone": "(254)954-1289", - "website": "demarco.info", - "company": { - "name": "Keebler LLC", - "catchPhrase": "User-centric fault-tolerant solution", - "bs": "revolutionize end-to-end systems" - } - }, - { - "id": 6, - "name": "Mrs. Dennis Schulist", - "username": "Leopoldo_Corkery", - "email": "Karley_Dach@jasper.info", - "address": { - "street": "Norberto Crossing", - "suite": "Apt. 950", - "city": "South Christy", - "zipcode": "23505-1337", - "geo": { - "lat": "-71.4197", - "lng": "71.7478" - } - }, - "phone": "1-477-935-8478 x6430", - "website": "ola.org", - "company": { - "name": "Considine-Lockman", - "catchPhrase": "Synchronised bottom-line interface", - "bs": "e-enable innovative applications" - } - }, - { - "id": 7, - "name": "Kurtis Weissnat", - "username": "Elwyn.Skiles", - "email": "Telly.Hoeger@billy.biz", - "address": { - "street": "Rex Trail", - "suite": "Suite 280", - "city": "Howemouth", - "zipcode": "58804-1099", - "geo": { - "lat": "24.8918", - "lng": "21.8984" - } - }, - "phone": "210.067.6132", - "website": "elvis.io", - "company": { - "name": "Johns Group", - "catchPhrase": "Configurable multimedia task-force", - "bs": "generate enterprise e-tailers" - } - }, - { - "id": 8, - "name": "Nicholas Runolfsdottir V", - "username": "Maxime_Nienow", - "email": "Sherwood@rosamond.me", - "address": { - "street": "Ellsworth Summit", - "suite": "Suite 729", - "city": "Aliyaview", - "zipcode": "45169", - "geo": { - "lat": "-14.3990", - "lng": "-120.7677" - } - }, - "phone": "586.493.6943 x140", - "website": "jacynthe.com", - "company": { - "name": "Abernathy Group", - "catchPhrase": "Implemented secondary concept", - "bs": "e-enable extensible e-tailers" - } - }, - { - "id": 9, - "name": "Glenna Reichert", - "username": "Delphine", - "email": "Chaim_McDermott@dana.io", - "address": { - "street": "Dayna Park", - "suite": "Suite 449", - "city": "Bartholomebury", - "zipcode": "76495-3109", - "geo": { - "lat": "24.6463", - "lng": "-168.8889" - } - }, - "phone": "(775)976-6794 x41206", - "website": "conrad.com", - "company": { - "name": "Yost and Sons", - "catchPhrase": "Switchable contextually-based project", - "bs": "aggregate real-time technologies" - } - }, - { - "id": 10, - "name": "Clementina DuBuque", - "username": "Moriah.Stanton", - "email": "Rey.Padberg@karina.biz", - "address": { - "street": "Kattie Turnpike", - "suite": "Suite 198", - "city": "Lebsackbury", - "zipcode": "31428-2261", - "geo": { - "lat": "-38.2386", - "lng": "57.2232" - } - }, - "phone": "024-648-3804", - "website": "ambrose.net", - "company": { - "name": "Hoeger LLC", - "catchPhrase": "Centralized empowering task-force", - "bs": "target end-to-end models" - } - } -] \ No newline at end of file diff --git a/jam-ui/cypress/integration/auth/signup_signin.spec.js b/jam-ui/cypress/integration/auth/signup_signin.spec.js index deee987f1..977da4870 100644 --- a/jam-ui/cypress/integration/auth/signup_signin.spec.js +++ b/jam-ui/cypress/integration/auth/signup_signin.spec.js @@ -1,6 +1,5 @@ /// -import {email} from 'chance'; describe('sign up and sign in', () => { it('redirects to rails app', () => { @@ -36,7 +35,7 @@ describe('sign up and sign in', () => { // }) }) -describe.only('Dashboard', () => { +describe.only('Login to legacy app', () => { before(() => { cy.visit(`${Cypress.env('legacyBaseUrl')}/signin`) cy.get('.signin-form').first().within(() => { diff --git a/jam-ui/cypress/integration/friends/friends-list.spec.js b/jam-ui/cypress/integration/friends/friends-page.spec.js similarity index 92% rename from jam-ui/cypress/integration/friends/friends-list.spec.js rename to jam-ui/cypress/integration/friends/friends-page.spec.js index 64757135e..94126ade4 100644 --- a/jam-ui/cypress/integration/friends/friends-list.spec.js +++ b/jam-ui/cypress/integration/friends/friends-page.spec.js @@ -16,13 +16,12 @@ describe('Friends page without data', () => { }) }) - describe('Friends page with data', () => { beforeEach(() => { cy.stubAuthenticate({ id: '2'}); //currentUser id is 2 - people.yaml fixture cy.intercept('POST', /\S+\/filter/, { fixture: 'people' }); }); - + describe('friends list', () => { beforeEach(() => { cy.visit('/friends'); @@ -125,6 +124,7 @@ describe('Friends page with data', () => { cy.get('[data-testid=profileSidePanel]') .find('[data-testid=connect]') .should('be.disabled'); + cy.contains('Friend request was sent') }); it('remove friend', () => { @@ -189,15 +189,15 @@ describe('Friends page with data', () => { 'text_messages_page2', 'text_messages_page3' ] - // messageFixtures.forEach((fixture) => { - // cy.fixture(fixture).then((json) => { - // cy.intercept('GET', /\S+\/text_messages\S+/, json) - // cy.get('.modal-body .ScrollbarsCustom').trigger('mouseover').scrollTo('bottom') - // cy.get('.modal-body .ScrollbarsCustom').trigger('mouseover').scrollTo('top') - // numberOfMessages = numberOfMessages + 10 - // cy.get('.text-message-row').should('have.length', numberOfMessages) - // }) - // }) + messageFixtures.forEach((fixture) => { + cy.fixture(fixture).then((json) => { + cy.intercept('GET', /\S+\/text_messages\S+/, json) + cy.get('.modal-body .ScrollbarsCustom').trigger('mouseover').scrollTo('bottom') + cy.get('.modal-body .ScrollbarsCustom').trigger('mouseover').scrollTo('top') + numberOfMessages = numberOfMessages + 10 + cy.get('.text-message-row').should('have.length', numberOfMessages) + }) + }) cy.get('button').contains('Close').should('not.be.disabled').click() @@ -243,11 +243,11 @@ describe('Friends page with data', () => { }) it.skip('shows received message by other user', () => { - //TODO: this should be test in e2e test (without faking backend api intractions) + //TODO: this should be test in e2e test }) - }) + }); diff --git a/jam-ui/cypress/integration/layout/navigation.spec.js b/jam-ui/cypress/integration/layout/navigation.spec.js index 237ff45a8..60c6d0f91 100644 --- a/jam-ui/cypress/integration/layout/navigation.spec.js +++ b/jam-ui/cypress/integration/layout/navigation.spec.js @@ -22,7 +22,7 @@ describe("Top Navigation", () => { it("does not show user dropdown", () => { cy.contains("Signin to begin") - cy.get('a.btn').should('have.text', 'Signin') + cy.get('a.btn').should('have.text', 'Sign in') cy.get('[data-testid=navbarTopProfileDropdown]').should('not.exist') }); @@ -40,6 +40,25 @@ describe("Top Navigation", () => { showProfileDropdown() }) }) + + describe('header notifications', () => { + beforeEach(() => { + cy.stubAuthenticate() + cy.intercept('GET', /\S+\/notifications/, { fixture: 'notifications'} ) + cy.intercept('GET', /\S+\/profile\S+/, { fixture: 'person' }); + cy.visit('/') + }) + + it('shows notifications', () => { + cy.get('[data-testid=notificationDropdown]').should('not.be.visible') + cy.get('.notification-indicator').trigger('mouseover') + cy.get('[data-testid=notificationDropdown]').should('be.visible') + cy.get('[data-testid=notificationDropdown] .list-group-item').should('have.length', 3) + cy.get('[data-testid=notificationDropdown]').contains('View all').click() //view all notifications + cy.url().should('include', '/notifications') + }) + }) + }); diff --git a/jam-ui/cypress/screenshots/2-advanced-examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png b/jam-ui/cypress/screenshots/2-advanced-examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png deleted file mode 100644 index d17d346e7..000000000 Binary files a/jam-ui/cypress/screenshots/2-advanced-examples/cypress_api.spec.js/Cypress.config() -- Get and set configuration options (failed).png and /dev/null differ diff --git a/jam-ui/cypress/screenshots/2-advanced-examples/misc.spec.js/my-image.png b/jam-ui/cypress/screenshots/2-advanced-examples/misc.spec.js/my-image.png deleted file mode 100644 index 51af8456a..000000000 Binary files a/jam-ui/cypress/screenshots/2-advanced-examples/misc.spec.js/my-image.png and /dev/null differ diff --git a/jam-ui/cypress/screenshots/auth/signup_signin.spec.js/Login to legacy app -- is on dashboard (failed).png b/jam-ui/cypress/screenshots/auth/signup_signin.spec.js/Login to legacy app -- is on dashboard (failed).png new file mode 100644 index 000000000..5c5bb21af Binary files /dev/null and b/jam-ui/cypress/screenshots/auth/signup_signin.spec.js/Login to legacy app -- is on dashboard (failed).png differ diff --git a/jam-ui/cypress/screenshots/friends/friends-list.spec.js/Friends page with data -- making friendship -- add friend (failed).png b/jam-ui/cypress/screenshots/friends/friends-list.spec.js/Friends page with data -- making friendship -- add friend (failed).png new file mode 100644 index 000000000..1f5de7c95 Binary files /dev/null and b/jam-ui/cypress/screenshots/friends/friends-list.spec.js/Friends page with data -- making friendship -- add friend (failed).png differ diff --git a/jam-ui/cypress/videos/auth/signup_signin.spec.js.mp4 b/jam-ui/cypress/videos/auth/signup_signin.spec.js.mp4 new file mode 100644 index 000000000..60eec5c9b Binary files /dev/null and b/jam-ui/cypress/videos/auth/signup_signin.spec.js.mp4 differ diff --git a/jam-ui/cypress/videos/friends/friends-list.spec.js.mp4 b/jam-ui/cypress/videos/friends/friends-list.spec.js.mp4 index 0c7eaa5d0..d3db99641 100644 Binary files a/jam-ui/cypress/videos/friends/friends-list.spec.js.mp4 and b/jam-ui/cypress/videos/friends/friends-list.spec.js.mp4 differ diff --git a/jam-ui/cypress/videos/layout/navigation.spec.js.mp4 b/jam-ui/cypress/videos/layout/navigation.spec.js.mp4 index 3fa1479f3..0d1dace72 100644 Binary files a/jam-ui/cypress/videos/layout/navigation.spec.js.mp4 and b/jam-ui/cypress/videos/layout/navigation.spec.js.mp4 differ diff --git a/jam-ui/package-lock.json b/jam-ui/package-lock.json index 0122289cc..86a81f498 100644 --- a/jam-ui/package-lock.json +++ b/jam-ui/package-lock.json @@ -1736,6 +1736,808 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" }, + "@playwright/test": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.15.2.tgz", + "integrity": "sha512-pDEydzpVdABAySMCUXD4h81nqAN0UjpNZeeheuZaG1AH6ElV9g5vOaj1pfFlRi5Io6gjbVbcdNOrAE4mCb/EZw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/core": "^7.14.8", + "@babel/plugin-proposal-class-properties": "^7.14.5", + "@babel/plugin-proposal-dynamic-import": "^7.14.5", + "@babel/plugin-proposal-export-namespace-from": "^7.14.5", + "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", + "@babel/plugin-proposal-numeric-separator": "^7.14.5", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", + "@babel/plugin-proposal-private-methods": "^7.14.5", + "@babel/plugin-proposal-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.14.5", + "@babel/preset-typescript": "^7.14.5", + "colors": "^1.4.0", + "commander": "^6.1.0", + "debug": "^4.1.1", + "expect": "^26.4.2", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.0", + "jpeg-js": "^0.4.2", + "mime": "^2.4.6", + "minimatch": "^3.0.3", + "ms": "^2.1.2", + "open": "^8.2.1", + "pirates": "^4.0.1", + "pixelmatch": "^5.2.1", + "pngjs": "^5.0.0", + "progress": "^2.0.3", + "proper-lockfile": "^4.1.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "source-map-support": "^0.4.18", + "stack-utils": "^2.0.3", + "ws": "^7.4.6", + "yazl": "^2.5.1" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", + "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz", + "integrity": "sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4" + } + }, + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", + "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz", + "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", + "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz", + "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", + "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", + "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", + "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", + "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz", + "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz", + "integrity": "sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.15.4", + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", + "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-simple-access": "^7.15.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.15.8.tgz", + "integrity": "sha512-ZXIkJpbaf6/EsmjeTbiJN/yMxWPFWvlr7sEG1P95Xb4S4IBcrf2n7s/fItIhsAmOf8oSh3VJPDppO6ExfAfKRQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + } + }, + "@babel/preset-typescript": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.15.0.tgz", + "integrity": "sha512-lt0Y/8V3y06Wq/8H/u0WakrqciZ7Fz7mwPDHWUJAXlABL5hiUG42BNlRXiELNjeWjO5rWmnNKlx+yzJvxezHow==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.15.0" + } + }, + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + } + }, + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "open": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.3.0.tgz", + "integrity": "sha512-7INcPWb1UcOwSQxAXTnBJ+FxVV4MPs/X++FWWBtgY69/J5lc+tCteMt/oFK1MnkyHC4VILLa9ntmwKTwDR4Q9w==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ws": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "dev": true + } + } + }, "@reduxjs/toolkit": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.1.tgz", @@ -2061,6 +2863,16 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" }, + "@types/yauzl": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", + "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz", @@ -2369,6 +3181,15 @@ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -4173,6 +4994,12 @@ } } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", @@ -4779,6 +5606,12 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5645,6 +6478,12 @@ "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", "dev": true }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -7262,6 +8101,29 @@ } } }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -7378,6 +8240,15 @@ } } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "figgy-pudding": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", @@ -9181,15 +10052,25 @@ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "hyphenate-style-name": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz", "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -9823,6 +10704,17 @@ "requires": { "node-fetch": "^1.0.1", "whatwg-fetch": ">=0.10.0" + }, + "dependencies": { + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } } }, "isstream": { @@ -10422,6 +11314,12 @@ } } }, + "jpeg-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", + "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", + "dev": true + }, "js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", @@ -11923,15 +12821,6 @@ "tslib": "^2.0.3" } }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -12925,6 +13814,12 @@ "sha.js": "^2.4.8" } }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -12961,6 +13856,23 @@ "node-modules-regexp": "^1.0.0" } }, + "pixelmatch": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", + "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", + "dev": true, + "requires": { + "pngjs": "^4.0.1" + }, + "dependencies": { + "pngjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", + "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", + "dev": true + } + } + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -13036,6 +13948,12 @@ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, + "pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "dev": true + }, "pnp-webpack-plugin": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", @@ -14147,6 +15065,17 @@ "react-is": "^16.8.1" } }, + "proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -14156,6 +15085,12 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -19413,6 +20348,25 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } + }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/jam-ui/package.json b/jam-ui/package.json index 1cbee9886..54d6d51c4 100644 --- a/jam-ui/package.json +++ b/jam-ui/package.json @@ -80,12 +80,14 @@ "build": "react-scripts build", "eject": "react-scripts eject", "scss": "gulp", - "analyze": "npx source-map-explorer 'build/static/js/*.js'" + "analyze": "npx source-map-explorer 'build/static/js/*.js'", + "test": "playwright test" }, "eslintConfig": { "extends": "react-app" }, "devDependencies": { + "@playwright/test": "^1.15.2", "browser-sync": "^2.26.12", "eslint-config-prettier": "^4.2.0", "eslint-plugin-prettier": "^3.1.4", diff --git a/jam-ui/playwright.config.ts b/jam-ui/playwright.config.ts new file mode 100644 index 000000000..31bca5149 --- /dev/null +++ b/jam-ui/playwright.config.ts @@ -0,0 +1,57 @@ +import { PlaywrightTestConfig } from '@playwright/test'; + +const config: PlaywrightTestConfig = { + globalSetup: require.resolve('./test/config/global-setup'), + use: { + baseURL: 'http://beta.jamkazam.local:4000', + actionTimeout: 5000, + headless: true, + viewport: { width: 1280, height: 720}, + ignoreHTTPSErrors: true, + video: 'on-first-retry', + }, +}; + +export default config; + + +// const { devices } = require('@playwright/test'); + +// /** @type {import('@playwright/test').PlaywrightTestConfig} */ +// const config = { +// testDir: './test', +// workers: 2, +// retries: 2, +// use: { +// headless: false, +// viewport: { width: 1280, height: 720 }, +// launchOptions: { +// slowMo: 1000, +// }, +// video:"on", +// }, +// projects: [ +// { +// name: 'Desktop Chromium', +// use: { +// browserName: 'chromium', +// }, +// }, +// { name: 'Desktop Safari', +// use: { +// browserName: 'webkit', +// viewport: { width: 1200, height: 750 }, +// } +// }, +// // Test against mobile viewports. +// { name: 'Mobile Chrome', +// use: devices['Pixel 5'], +// }, +// { +// name: 'Mobile Safari', +// use: devices['iPhone 12'], +// }, +// ], +// }; + +// module.exports = config; \ No newline at end of file diff --git a/jam-ui/src/components/navbar/JKNotificationDropdown.js b/jam-ui/src/components/navbar/JKNotificationDropdown.js index a255eafe8..cdb6172d9 100644 --- a/jam-ui/src/components/navbar/JKNotificationDropdown.js +++ b/jam-ui/src/components/navbar/JKNotificationDropdown.js @@ -69,6 +69,7 @@ const JKNotificationDropdown = () => { limit: LIMIT }; await dispatch(fetchNotifications(options)).unwrap(); + console.log('NOTIFICATIONS', notifications); //setPage(prev => prev + 1); } catch (error) { console.log(error); @@ -105,7 +106,7 @@ const JKNotificationDropdown = () => { > - + {/* diff --git a/jam-ui/src/components/notification/JKTextMessageNotification.js b/jam-ui/src/components/notification/JKTextMessageNotification.js index 72db3516b..a1d4145ef 100644 --- a/jam-ui/src/components/notification/JKTextMessageNotification.js +++ b/jam-ui/src/components/notification/JKTextMessageNotification.js @@ -25,7 +25,6 @@ function JKTextMessageNotification(props) { dispatch(fetchPerson({ userId: source_user_id })) .unwrap() .then(resp => { - console.log('after fetch person', resp); dispatch(addPerson(resp)) }) .catch(error => console.log(error)); diff --git a/jam-ui/src/components/profile/JKConnectButton.js b/jam-ui/src/components/profile/JKConnectButton.js index e551ecc08..6d780e6b3 100644 --- a/jam-ui/src/components/profile/JKConnectButton.js +++ b/jam-ui/src/components/profile/JKConnectButton.js @@ -1,5 +1,6 @@ import React, {useEffect, useState} from 'react'; import {addFriend as connect, removeFriend as disconnect} from '../../helpers/rest'; +import { toast } from 'react-toastify'; const JKConnectButton = (props) => { const { user, currentUser, addContent, removeContent, cssClasses } = props @@ -12,13 +13,17 @@ const JKConnectButton = (props) => { }, [user]) const addFriend = () => { + setPendingFriendRequest(true) connect(currentUser.id, user.id) .then(resp => { if(resp.ok && resp.status === 201){ - setPendingFriendRequest(true) + toast.success('Friend request was sent successfully') } }) - .catch(err => console.log(err)) + .catch(err => { + toast.error('An error encountered when sending friend request') + setPendingFriendRequest(false) + }) } const removeFriend = () => { @@ -26,15 +31,18 @@ const JKConnectButton = (props) => { .then(resp => { if(resp.ok){ setIsFriend(false) + setPendingFriendRequest(false) } }) - .catch(err => console.log(err)) + .catch(err => { + toast.error('An error encountered when removing friend') + }) } const buttonTitle = () => { let title; if (pendingFriendRequest) { - title = 'Thre is a pending friend request'; + title = 'There is a pending friend request'; } else if (!isFriend) { title = 'Send friend request'; } else if (isFriend) { diff --git a/jam-ui/src/layouts/JKLayout.js b/jam-ui/src/layouts/JKLayout.js index b387ba0b8..2cdd3ad09 100644 --- a/jam-ui/src/layouts/JKLayout.js +++ b/jam-ui/src/layouts/JKLayout.js @@ -14,7 +14,7 @@ const Layout = () => { - } position={toast.POSITION.BOTTOM_LEFT} /> + } position={toast.POSITION.BOTTOM_RIGHT} /> ); }; diff --git a/jam-ui/test/config/global-setup.ts b/jam-ui/test/config/global-setup.ts new file mode 100644 index 000000000..1326d32da --- /dev/null +++ b/jam-ui/test/config/global-setup.ts @@ -0,0 +1,46 @@ +import { chromium, FullConfig, Page } from '@playwright/test'; +import {user1, user2 } from '../data/users'; + +async function signup(page: Page, email:string, password:string, first_name:string, Last_name:string){ + await page.goto('http://www.jamkazam.local:3000/sigup'); + await page.fill('input#jam_ruby_user_first_name', first_name); + await page.fill('input#jam_ruby_user_last_name', Last_name); + await page.fill('input#jam_ruby_user_email', email); + await page.fill('input#jam_ruby_user_password', password); + await page.fill('input#jam_ruby_user_password_confirmation', password); + await page.locator('input#jam_ruby_user_terms_of_service').check(); + await page.click('input[type="submit"]'); +} + +async function login(page: Page, email: string, password: string){ + await page.goto('http://www.jamkazam.local:3000/signin'); + await page.fill('input#session_email', email); + await page.fill('input#session_password', password); + await page.click('input[type="submit"]'); +} + +async function globalSetup(config: FullConfig) { + const browser = await chromium.launch(); + + const page1 = await browser.newPage(); + //signup user1 + await signup(page1, user1.email, user1.password, user1.first_name, user1.last_name) + // ... log in user1 + await login(page1, user1.email, user1.password) + await page1.context().storageState({ path: 'test/storageState/user1.json' }); + + const page2 = await browser.newPage(); + //signup user2 + await signup(page2, user2.email, user2.password, user2.first_name, user2.last_name) + // ... log in + await login(page2, user2.email, user2.password) + await page2.context().storageState({ path: 'test/storageState/user2.json' }); + + await browser.close(); +} + +async function globalTeardown(){ + //TODO: delete created users +} + +export default globalSetup; \ No newline at end of file diff --git a/jam-ui/test/data/users.js b/jam-ui/test/data/users.js new file mode 100644 index 000000000..b36421be6 --- /dev/null +++ b/jam-ui/test/data/users.js @@ -0,0 +1,18 @@ + + const user1 = { + id: '27bd4a30-d1b8-4eea-8454-01a104d59381', + email: 'nuwan@jamkazam.com', + password: 'jam123', + first_name: 'Nuwan', + last_name: 'Chathuranga' + } + + const user2 = { + id: 'a09f9a7e-afb7-489d-870d-e13a336e0b97', + email: 'nuwan+6@jamkazam.com', + password: 'jam123', + first_name: 'Seth', + last_name: 'Call' + } + + module.exports = { user1, user2 } \ No newline at end of file diff --git a/jam-ui/test/friends.spec.ts b/jam-ui/test/friends.spec.ts new file mode 100644 index 000000000..a881b7d33 --- /dev/null +++ b/jam-ui/test/friends.spec.ts @@ -0,0 +1,56 @@ +import { test, expect } from '@playwright/test'; + + +test.describe.serial('Friends page', () => { + test.describe.only('as User1', () => { + test.use({ storageState: 'test/storageState/user1.json' }); + + test.beforeAll(() => { + + }) + + test('Homepage', async ({ page }) => { + await page.goto('/') + await expect(page.locator('h1').first()).toHaveText('Dashboard - Home') + await expect(page.locator('data-testid=navbarTopProfileDropdown')).toContainText('Nuwan Chaturanga') + }); + + test('Friends page', async({ page }) => { + await page.goto('/friends') + await expect(page.locator('h5').first()).toHaveText('Find New Friends') + }) + + test.describe('Send friend request', () => { + test.beforeAll( async () => { + + }) + + test.only('Connect', async ({page, browser}) => { + await page.goto('/friends') + await expect(page.locator('data-testid=peopleListTable')).toContainText('Seth Call') + await page.locator('data-testid=peopleListTable').locator('text=Seth Call').click() + //await page.locator('data-testid=profileSidePanel').locator('data-testid=connect').click() + //await expect(page.locator('#flash')).toHaveText('Your friend request was sent successfully') + }) + + }) + + }) + + test.describe('as User2', () => { + test.use({ storageState: 'test/storageState/user2.json' }); + + test('Homepage', async ({ page }) => { + await page.goto('/') + await expect(page.locator('h1').first()).toHaveText('Dashboard - Home') + await expect(page.locator('data-testid=navbarTopProfileDropdown')).toContainText('Seth Call') + }); + + test('Friends page', async({ page }) => { + await page.goto('/friends') + await expect(page.locator('h5').first()).toHaveText('Find New Friends') + }) + + }) +}) + diff --git a/jam-ui/test/playwright.spec.ts b/jam-ui/test/playwright.spec.ts new file mode 100644 index 000000000..9c44df0be --- /dev/null +++ b/jam-ui/test/playwright.spec.ts @@ -0,0 +1,6 @@ +import { test, expect } from '@playwright/test'; +test('basic test', async ({ page }) => { + await page.goto('https://playwright.dev/'); + const title = page.locator('.navbar__inner .navbar__title'); + await expect(title).toHaveText('Playwright'); +}); diff --git a/jam-ui/test/storageState/user1.json b/jam-ui/test/storageState/user1.json new file mode 100644 index 000000000..5d87ff708 --- /dev/null +++ b/jam-ui/test/storageState/user1.json @@ -0,0 +1,95 @@ +{ + "cookies": [ + { + "sameSite": "Lax", + "name": "user_uuid", + "value": "2aa6e680-3390-4391-aa0f-121d677b460e", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439128, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "browser.timezone", + "value": "Asia%2FKolkata", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1665823128, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "origin", + "value": "%7B%22utm_source%22%3A%22organic%22%2C%22utm_medium%22%3A%22organic%22%2C%22utm_campaign%22%3A%22www.jamkazam.local%22%2C%22referrer%22%3A%22http%3A%2F%2Fwww.jamkazam.local%3A3000%2Fsignin%22%7D", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439128, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_ga", + "value": "GA1.1.921981718.1634287129", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1697359128, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_gid", + "value": "GA1.1.1844330619.1634287129", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1634373528, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_gat", + "value": "1", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1634287188, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "remember_token", + "value": "mS_Jut9bnHfkBILdVNB61g", + "domain": ".jamkazam.local", + "path": "/", + "expires": -1, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "jamkazam_user", + "value": "true", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439129, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_jamkazam_session", + "value": "WjREdTRjZ0p6WThhWkdnZTdXck5FY214cEJHaGJVS1NWNWszWnJSdFlGbGU4cGVLdXlnYzJYUkE5ekRGU1pjSUZMbEFicDN3YUF1elh2aG1ZMzdjNjVxa0xGMWR1cWs1ZUxRMHZHa3ltck5jeWlIb2dYcmpab2xJRmlJSXpBbGh4cGhQRS9uSTl1TytIQkVDZHRkeWFBPT0tLXBhb3puWUw1OFpYbStuZndCd0JZZ1E9PQ%3D%3D--28550b6657bd3382114910180ac98c3c331beaa6", + "domain": ".jamkazam.local", + "path": "/", + "expires": -1, + "httpOnly": true, + "secure": false + } + ], + "origins": [] +} \ No newline at end of file diff --git a/jam-ui/test/storageState/user2.json b/jam-ui/test/storageState/user2.json new file mode 100644 index 000000000..e427a6c60 --- /dev/null +++ b/jam-ui/test/storageState/user2.json @@ -0,0 +1,95 @@ +{ + "cookies": [ + { + "sameSite": "Lax", + "name": "user_uuid", + "value": "21327889-f0f8-4914-a6ca-05210cf2cc97", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439130, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "browser.timezone", + "value": "Asia%2FKolkata", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1665823130, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "origin", + "value": "%7B%22utm_source%22%3A%22organic%22%2C%22utm_medium%22%3A%22organic%22%2C%22utm_campaign%22%3A%22www.jamkazam.local%22%2C%22referrer%22%3A%22http%3A%2F%2Fwww.jamkazam.local%3A3000%2Fsignin%22%7D", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439130, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_ga", + "value": "GA1.1.269565883.1634287131", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1697359130, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_gid", + "value": "GA1.1.175739767.1634287131", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1634373530, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_gat", + "value": "1", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 1634287190, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "remember_token", + "value": "OHsenGlOljf6-5O6mcXndQ", + "domain": ".jamkazam.local", + "path": "/", + "expires": -1, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "jamkazam_user", + "value": "true", + "domain": "www.jamkazam.local", + "path": "/", + "expires": 2265439131, + "httpOnly": false, + "secure": false + }, + { + "sameSite": "Lax", + "name": "_jamkazam_session", + "value": "eDVHVDRBTld5SGNhaFVMNEwxY3VrVVRBeStEZkNvdzJuL0x1cDhBZ3RLUHVNbytpTUFBM1k2M1Y3bEJTQXhKa0ZoRjNYWFhYbUNLTjRydUVhSUVBV2c5ZWNVeW9UYmlDYWNyYm5QQzFxT2g3emZ0Y1lkNk0zblVwMTd3a28rSnB1N1IwRmJsZTlGOFNSVlVWRDFxcFBRPT0tLXphU3NuRVNtNWxWM2VyendJcXNIMHc9PQ%3D%3D--eab86e92ca589397643b3e5d9bf3b219b6b36b3f", + "domain": ".jamkazam.local", + "path": "/", + "expires": -1, + "httpOnly": true, + "secure": false + } + ], + "origins": [] +} \ No newline at end of file