From 15358f7ab6d5ad867a78601d38f710d783ea4b95 Mon Sep 17 00:00:00 2001 From: Shane Osbourne Date: Thu, 18 May 2023 21:33:20 +0100 Subject: [PATCH] cypress removed --- cypress/configs/css-console-notify.js | 12 - cypress/configs/css-overlay-notify.js | 9 - cypress/configs/file-reloading.js | 10 - cypress/configs/file-watching-ignore.js | 7 - cypress/configs/logPrefix.js | 10 - cypress/configs/no-notify.js | 9 - cypress/fixtures/example.json | 5 - cypress/fixtures/profile.json | 5 - cypress/fixtures/users.json | 232 --- cypress/integration.backup/example_spec.js | 1497 ------------------- cypress/integration/connection-notify.js | 12 - cypress/integration/css-console-notify.js | 26 - cypress/integration/css-overlay-notify.js | 13 - cypress/integration/file-watching-ignore.js | 14 - cypress/integration/logPrefix.js | 22 - cypress/integration/no-notify.js | 14 - cypress/integration/ui-remote-debug.js | 28 - cypress/plugins/index.js | 17 - cypress/setup/bs-cli.js | 46 - cypress/setup/bs.js | 35 - cypress/support/commands.js | 25 - cypress/support/index.js | 20 - examples/basic/run.js | 1 - tests/examples/basic/basic.spec.ts | 33 + tests/utils.ts | 5 +- 25 files changed, 37 insertions(+), 2070 deletions(-) delete mode 100644 cypress/configs/css-console-notify.js delete mode 100644 cypress/configs/css-overlay-notify.js delete mode 100644 cypress/configs/file-reloading.js delete mode 100644 cypress/configs/file-watching-ignore.js delete mode 100644 cypress/configs/logPrefix.js delete mode 100644 cypress/configs/no-notify.js delete mode 100644 cypress/fixtures/example.json delete mode 100644 cypress/fixtures/profile.json delete mode 100644 cypress/fixtures/users.json delete mode 100644 cypress/integration.backup/example_spec.js delete mode 100644 cypress/integration/connection-notify.js delete mode 100644 cypress/integration/css-console-notify.js delete mode 100644 cypress/integration/css-overlay-notify.js delete mode 100644 cypress/integration/file-watching-ignore.js delete mode 100644 cypress/integration/logPrefix.js delete mode 100644 cypress/integration/no-notify.js delete mode 100644 cypress/integration/ui-remote-debug.js delete mode 100644 cypress/plugins/index.js delete mode 100644 cypress/setup/bs-cli.js delete mode 100644 cypress/setup/bs.js delete mode 100644 cypress/support/commands.js delete mode 100644 cypress/support/index.js diff --git a/cypress/configs/css-console-notify.js b/cypress/configs/css-console-notify.js deleted file mode 100644 index ae26b4fe9..000000000 --- a/cypress/configs/css-console-notify.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - watch: true, - online: false, - // logLevel: 'silent', - minify: false, - injectNotification: 'console', - ghostMode: { - clicks: false, - } -}; diff --git a/cypress/configs/css-overlay-notify.js b/cypress/configs/css-overlay-notify.js deleted file mode 100644 index 43e990f2c..000000000 --- a/cypress/configs/css-overlay-notify.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - watch: true, - online: false, - logLevel: 'silent', - minify: false, - injectNotification: 'overlay' -}; diff --git a/cypress/configs/file-reloading.js b/cypress/configs/file-reloading.js deleted file mode 100644 index d8cf9ed30..000000000 --- a/cypress/configs/file-reloading.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - watch: true, - online: false, - // logLevel: 'silent', - minify: false, - // ghostMode: { scroll: true }, - // injectNotification: 'console' -}; diff --git a/cypress/configs/file-watching-ignore.js b/cypress/configs/file-watching-ignore.js deleted file mode 100644 index 69ecac467..000000000 --- a/cypress/configs/file-watching-ignore.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - online: false, - minify: false, - files: 'packages/browser-sync/test/fixtures', -}; diff --git a/cypress/configs/logPrefix.js b/cypress/configs/logPrefix.js deleted file mode 100644 index a0a92358d..000000000 --- a/cypress/configs/logPrefix.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - watch: true, - online: false, - logLevel: 'silent', - minify: false, - logPrefix: 'WSK', - injectNotification: 'console', -}; diff --git a/cypress/configs/no-notify.js b/cypress/configs/no-notify.js deleted file mode 100644 index d82a44cd9..000000000 --- a/cypress/configs/no-notify.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - server: 'packages/browser-sync/test/fixtures', - open: false, - watch: true, - online: false, - logLevel: 'silent', - minify: false, - notify: false, -}; diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index da18d9352..000000000 --- a/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" -} \ No newline at end of file diff --git a/cypress/fixtures/profile.json b/cypress/fixtures/profile.json deleted file mode 100644 index b6c355ca5..000000000 --- a/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/cypress/fixtures/users.json b/cypress/fixtures/users.json deleted file mode 100644 index 79b699aa7..000000000 --- a/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/cypress/integration.backup/example_spec.js b/cypress/integration.backup/example_spec.js deleted file mode 100644 index ae2ace17c..000000000 --- a/cypress/integration.backup/example_spec.js +++ /dev/null @@ -1,1497 +0,0 @@ -// -// **** Kitchen Sink Tests **** -// -// This app was developed to demonstrate -// how to write tests in Cypress utilizing -// all of the available commands -// -// Feel free to modify this spec in your -// own application as a jumping off point - -// Please read our "Introduction to Cypress" -// https://on.cypress.io/introduction-to-cypress - -describe('Kitchen Sink', function () { - it('.should() - assert that is correct', function () { - // https://on.cypress.io/visit - cy.visit('https://example.cypress.io') - - // Here we've made our first assertion using a '.should()' command. - // An assertion is comprised of a chainer, subject, and optional value. - - // https://on.cypress.io/should - // https://on.cypress.io/and - - // https://on.cypress.io/title - cy.title().should('include', 'Kitchen Sink') - // ↲ ↲ ↲ - // subject chainer value - }) - - context('Querying', function () { - beforeEach(function () { - // Visiting our app before each test removes any state build up from - // previous tests. Visiting acts as if we closed a tab and opened a fresh one - cy.visit('https://example.cypress.io/commands/querying') - }) - - // Let's query for some DOM elements and make assertions - // The most commonly used query is 'cy.get()', you can - // think of this like the '$' in jQuery - - it('cy.get() - query DOM elements', function () { - // https://on.cypress.io/get - - // Get DOM elements by id - cy.get('#query-btn').should('contain', 'Button') - - // Get DOM elements by class - cy.get('.query-btn').should('contain', 'Button') - - cy.get('#querying .well>button:first').should('contain', 'Button') - // ↲ - // Use CSS selectors just like jQuery - }) - - it('cy.contains() - query DOM elements with matching content', function () { - // https://on.cypress.io/contains - cy.get('.query-list') - .contains('bananas').should('have.class', 'third') - - // we can pass a regexp to `.contains()` - cy.get('.query-list') - .contains(/^b\w+/).should('have.class', 'third') - - cy.get('.query-list') - .contains('apples').should('have.class', 'first') - - // passing a selector to contains will yield the selector containing the text - cy.get('#querying') - .contains('ul', 'oranges').should('have.class', 'query-list') - - // `.contains()` will favor input[type='submit'], - // button, a, and label over deeper elements inside them - // this will not yield the <span> inside the button, - // but the <button> itself - cy.get('.query-button') - .contains('Save Form').should('have.class', 'btn') - }) - - it('.within() - query DOM elements within a specific element', function () { - // https://on.cypress.io/within - cy.get('.query-form').within(function () { - cy.get('input:first').should('have.attr', 'placeholder', 'Email') - cy.get('input:last').should('have.attr', 'placeholder', 'Password') - }) - }) - - it('cy.root() - query the root DOM element', function () { - // https://on.cypress.io/root - // By default, root is the document - cy.root().should('match', 'html') - - cy.get('.query-ul').within(function () { - // In this within, the root is now the ul DOM element - cy.root().should('have.class', 'query-ul') - }) - }) - }) - - context('Traversal', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/traversal') - }) - - // Let's query for some DOM elements and make assertions - - it('.children() - get child DOM elements', function () { - // https://on.cypress.io/children - cy.get('.traversal-breadcrumb').children('.active') - .should('contain', 'Data') - }) - - it('.closest() - get closest ancestor DOM element', function () { - // https://on.cypress.io/closest - cy.get('.traversal-badge').closest('ul') - .should('have.class', 'list-group') - }) - - it('.eq() - get a DOM element at a specific index', function () { - // https://on.cypress.io/eq - cy.get('.traversal-list>li').eq(1).should('contain', 'siamese') - }) - - it('.filter() - get DOM elements that match the selector', function () { - // https://on.cypress.io/filter - cy.get('.traversal-nav>li').filter('.active').should('contain', 'About') - }) - - it('.find() - get descendant DOM elements of the selector', function () { - // https://on.cypress.io/find - cy.get('.traversal-pagination').find('li').find('a') - .should('have.length', 7) - }) - - it('.first() - get first DOM element', function () { - // https://on.cypress.io/first - cy.get('.traversal-table td').first().should('contain', '1') - }) - - it('.last() - get last DOM element', function () { - // https://on.cypress.io/last - cy.get('.traversal-buttons .btn').last().should('contain', 'Submit') - }) - - it('.next() - get next sibling DOM element', function () { - // https://on.cypress.io/next - cy.get('.traversal-ul').contains('apples').next().should('contain', 'oranges') - }) - - it('.nextAll() - get all next sibling DOM elements', function () { - // https://on.cypress.io/nextall - cy.get('.traversal-next-all').contains('oranges') - .nextAll().should('have.length', 3) - }) - - it('.nextUntil() - get next sibling DOM elements until next el', function () { - // https://on.cypress.io/nextuntil - cy.get('#veggies').nextUntil('#nuts').should('have.length', 3) - }) - - it('.not() - remove DOM elements from set of DOM elements', function () { - // https://on.cypress.io/not - cy.get('.traversal-disabled .btn').not('[disabled]').should('not.contain', 'Disabled') - }) - - it('.parent() - get parent DOM element from DOM elements', function () { - // https://on.cypress.io/parent - cy.get('.traversal-mark').parent().should('contain', 'Morbi leo risus') - }) - - it('.parents() - get parent DOM elements from DOM elements', function () { - // https://on.cypress.io/parents - cy.get('.traversal-cite').parents().should('match', 'blockquote') - }) - - it('.parentsUntil() - get parent DOM elements from DOM elements until el', function () { - // https://on.cypress.io/parentsuntil - cy.get('.clothes-nav').find('.active').parentsUntil('.clothes-nav') - .should('have.length', 2) - }) - - it('.prev() - get previous sibling DOM element', function () { - // https://on.cypress.io/prev - cy.get('.birds').find('.active').prev().should('contain', 'Lorikeets') - }) - - it('.prevAll() - get all previous sibling DOM elements', function () { - // https://on.cypress.io/prevAll - cy.get('.fruits-list').find('.third').prevAll().should('have.length', 2) - }) - - it('.prevUntil() - get all previous sibling DOM elements until el', function () { - // https://on.cypress.io/prevUntil - cy.get('.foods-list').find('#nuts').prevUntil('#veggies') - }) - - it('.siblings() - get all sibling DOM elements', function () { - // https://on.cypress.io/siblings - cy.get('.traversal-pills .active').siblings().should('have.length', 2) - }) - }) - - context('Actions', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/actions') - }) - - // Let's perform some actions on DOM elements - // https://on.cypress.io/interacting-with-elements - - it('.type() - type into a DOM element', function () { - // https://on.cypress.io/type - cy.get('.action-email') - .type('fake@email.com').should('have.value', 'fake@email.com') - - // .type() with special character sequences - .type('{leftarrow}{rightarrow}{uparrow}{downarrow}') - .type('{del}{selectall}{backspace}') - - // .type() with key modifiers - .type('{alt}{option}') //these are equivalent - .type('{ctrl}{control}') //these are equivalent - .type('{meta}{command}{cmd}') //these are equivalent - .type('{shift}') - - // Delay each keypress by 0.1 sec - .type('slow.typing@email.com', { delay: 100 }) - .should('have.value', 'slow.typing@email.com') - - cy.get('.action-disabled') - // Ignore error checking prior to type - // like whether the input is visible or disabled - .type('disabled error checking', { force: true }) - .should('have.value', 'disabled error checking') - }) - - it('.focus() - focus on a DOM element', function () { - // https://on.cypress.io/focus - cy.get('.action-focus').focus() - .should('have.class', 'focus') - .prev().should('have.attr', 'style', 'color: orange;') - }) - - it('.blur() - blur off a DOM element', function () { - // https://on.cypress.io/blur - cy.get('.action-blur').type('I\'m about to blur').blur() - .should('have.class', 'error') - .prev().should('have.attr', 'style', 'color: red;') - }) - - it('.clear() - clears an input or textarea element', function () { - // https://on.cypress.io/clear - cy.get('.action-clear').type('We are going to clear this text') - .should('have.value', 'We are going to clear this text') - .clear() - .should('have.value', '') - }) - - it('.submit() - submit a form', function () { - // https://on.cypress.io/submit - cy.get('.action-form') - .find('[type="text"]').type('HALFOFF') - cy.get('.action-form').submit() - .next().should('contain', 'Your form has been submitted!') - }) - - it('.click() - click on a DOM element', function () { - // https://on.cypress.io/click - cy.get('.action-btn').click() - - // You can click on 9 specific positions of an element: - // ----------------------------------- - // | topLeft top topRight | - // | | - // | | - // | | - // | left center right | - // | | - // | | - // | | - // | bottomLeft bottom bottomRight | - // ----------------------------------- - - // clicking in the center of the element is the default - cy.get('#action-canvas').click() - - cy.get('#action-canvas').click('topLeft') - cy.get('#action-canvas').click('top') - cy.get('#action-canvas').click('topRight') - cy.get('#action-canvas').click('left') - cy.get('#action-canvas').click('right') - cy.get('#action-canvas').click('bottomLeft') - cy.get('#action-canvas').click('bottom') - cy.get('#action-canvas').click('bottomRight') - - // .click() accepts an x and y coordinate - // that controls where the click occurs :) - - cy.get('#action-canvas') - .click(80, 75) // click 80px on x coord and 75px on y coord - .click(170, 75) - .click(80, 165) - .click(100, 185) - .click(125, 190) - .click(150, 185) - .click(170, 165) - - // click multiple elements by passing multiple: true - cy.get('.action-labels>.label').click({ multiple: true }) - - // Ignore error checking prior to clicking - // like whether the element is visible, clickable or disabled - // this button below is covered by another element. - cy.get('.action-opacity>.btn').click({ force: true }) - }) - - it('.dblclick() - double click on a DOM element', function () { - // Our app has a listener on 'dblclick' event in our 'scripts.js' - // that hides the div and shows an input on double click - - // https://on.cypress.io/dblclick - cy.get('.action-div').dblclick().should('not.be.visible') - cy.get('.action-input-hidden').should('be.visible') - }) - - it('cy.check() - check a checkbox or radio element', function () { - // By default, .check() will check all - // matching checkbox or radio elements in succession, one after another - - // https://on.cypress.io/check - cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]') - .check().should('be.checked') - - cy.get('.action-radios [type="radio"]').not('[disabled]') - .check().should('be.checked') - - // .check() accepts a value argument - // that checks only checkboxes or radios - // with matching values - cy.get('.action-radios [type="radio"]').check('radio1').should('be.checked') - - // .check() accepts an array of values - // that checks only checkboxes or radios - // with matching values - cy.get('.action-multiple-checkboxes [type="checkbox"]') - .check(['checkbox1', 'checkbox2']).should('be.checked') - - // Ignore error checking prior to checking - // like whether the element is visible, clickable or disabled - // this checkbox below is disabled. - cy.get('.action-checkboxes [disabled]') - .check({ force: true }).should('be.checked') - - cy.get('.action-radios [type="radio"]') - .check('radio3', { force: true }).should('be.checked') - }) - - it('.uncheck() - uncheck a checkbox element', function () { - // By default, .uncheck() will uncheck all matching - // checkbox elements in succession, one after another - - // https://on.cypress.io/uncheck - cy.get('.action-check [type="checkbox"]') - .not('[disabled]') - .uncheck().should('not.be.checked') - - // .uncheck() accepts a value argument - // that unchecks only checkboxes - // with matching values - cy.get('.action-check [type="checkbox"]') - .check('checkbox1') - .uncheck('checkbox1').should('not.be.checked') - - // .uncheck() accepts an array of values - // that unchecks only checkboxes or radios - // with matching values - cy.get('.action-check [type="checkbox"]') - .check(['checkbox1', 'checkbox3']) - .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') - - // Ignore error checking prior to unchecking - // like whether the element is visible, clickable or disabled - // this checkbox below is disabled. - cy.get('.action-check [disabled]') - .uncheck({ force: true }).should('not.be.checked') - }) - - it('.select() - select an option in a <select> element', function () { - // https://on.cypress.io/select - - // Select option with matching text content - cy.get('.action-select').select('apples') - - // Select option with matching value - cy.get('.action-select').select('fr-bananas') - - // Select options with matching text content - cy.get('.action-select-multiple') - .select(['apples', 'oranges', 'bananas']) - - // Select options with matching values - cy.get('.action-select-multiple') - .select(['fr-apples', 'fr-oranges', 'fr-bananas']) - }) - - it('.scrollIntoView() - scroll an element into view', function () { - // https://on.cypress.io/scrollintoview - - // normally all of these buttons are hidden, because they're not within - // the viewable area of their parent (we need to scroll to see them) - cy.get('#scroll-horizontal button') - .should('not.be.visible') - - // scroll the button into view, as if the user had scrolled - cy.get('#scroll-horizontal button').scrollIntoView() - .should('be.visible') - - cy.get('#scroll-vertical button') - .should('not.be.visible') - - // Cypress handles the scroll direction needed - cy.get('#scroll-vertical button').scrollIntoView() - .should('be.visible') - - cy.get('#scroll-both button') - .should('not.be.visible') - - // Cypress knows to scroll to the right and down - cy.get('#scroll-both button').scrollIntoView() - .should('be.visible') - }) - - it('cy.scrollTo() - scroll the window or element to a position', function () { - - // https://on.cypress.io/scrollTo - - // You can scroll to 9 specific positions of an element: - // ----------------------------------- - // | topLeft top topRight | - // | | - // | | - // | | - // | left center right | - // | | - // | | - // | | - // | bottomLeft bottom bottomRight | - // ----------------------------------- - - // if you chain .scrollTo() off of cy, we will - // scroll the entire window - cy.scrollTo('bottom') - - cy.get('#scrollable-horizontal').scrollTo('right') - - // or you can scroll to a specific coordinate: - // (x axis, y axis) in pixels - cy.get('#scrollable-vertical').scrollTo(250, 250) - - // or you can scroll to a specific percentage - // of the (width, height) of the element - cy.get('#scrollable-both').scrollTo('75%', '25%') - - // control the easing of the scroll (default is 'swing') - cy.get('#scrollable-vertical').scrollTo('center', { easing: 'linear' }) - - // control the duration of the scroll (in ms) - cy.get('#scrollable-both').scrollTo('center', { duration: 2000 }) - }) - - it('.trigger() - trigger an event on a DOM element', function () { - // To interact with a range input (slider), we need to set its value and - // then trigger the appropriate event to signal it has changed - - // Here, we invoke jQuery's val() method to set the value - // and trigger the 'change' event - - // Note that some implementations may rely on the 'input' event, - // which is fired as a user moves the slider, but is not supported - // by some browsers - - // https://on.cypress.io/trigger - cy.get('.trigger-input-range') - .invoke('val', 25) - .trigger('change') - .get('input[type=range]').siblings('p') - .should('have.text', '25') - - // See our example recipes for more examples of using trigger - // https://on.cypress.io/examples - }) - }) - - context('Window', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/window') - }) - - it('cy.window() - get the global window object', function () { - // https://on.cypress.io/window - cy.window().should('have.property', 'top') - }) - - it('cy.document() - get the document object', function () { - // https://on.cypress.io/document - cy.document().should('have.property', 'charset').and('eq', 'UTF-8') - }) - - it('cy.title() - get the title', function () { - // https://on.cypress.io/title - cy.title().should('include', 'Kitchen Sink') - }) - }) - - context('Viewport', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/viewport') - }) - - it('cy.viewport() - set the viewport size and dimension', function () { - - cy.get('#navbar').should('be.visible') - - // https://on.cypress.io/viewport - cy.viewport(320, 480) - - // the navbar should have collapse since our screen is smaller - cy.get('#navbar').should('not.be.visible') - cy.get('.navbar-toggle').should('be.visible').click() - cy.get('.nav').find('a').should('be.visible') - - // lets see what our app looks like on a super large screen - cy.viewport(2999, 2999) - - // cy.viewport() accepts a set of preset sizes - // to easily set the screen to a device's width and height - - // We added a cy.wait() between each viewport change so you can see - // the change otherwise it's a little too fast to see :) - - cy.viewport('macbook-15') - cy.wait(200) - cy.viewport('macbook-13') - cy.wait(200) - cy.viewport('macbook-11') - cy.wait(200) - cy.viewport('ipad-2') - cy.wait(200) - cy.viewport('ipad-mini') - cy.wait(200) - cy.viewport('iphone-6+') - cy.wait(200) - cy.viewport('iphone-6') - cy.wait(200) - cy.viewport('iphone-5') - cy.wait(200) - cy.viewport('iphone-4') - cy.wait(200) - cy.viewport('iphone-3') - cy.wait(200) - - // cy.viewport() accepts an orientation for all presets - // the default orientation is 'portrait' - cy.viewport('ipad-2', 'portrait') - cy.wait(200) - cy.viewport('iphone-4', 'landscape') - cy.wait(200) - - // The viewport will be reset back to the default dimensions - // in between tests (the default is set in cypress.json) - }) - }) - - context('Location', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/location') - }) - - // We look at the url to make assertions - // about the page's state - - it('cy.hash() - get the current URL hash', function () { - // https://on.cypress.io/hash - cy.hash().should('be.empty') - }) - - it('cy.location() - get window.location', function () { - // https://on.cypress.io/location - cy.location().should(function (location) { - expect(location.hash).to.be.empty - expect(location.href).to.eq('https://example.cypress.io/commands/location') - expect(location.host).to.eq('example.cypress.io') - expect(location.hostname).to.eq('example.cypress.io') - expect(location.origin).to.eq('https://example.cypress.io') - expect(location.pathname).to.eq('/commands/location') - expect(location.port).to.eq('') - expect(location.protocol).to.eq('https:') - expect(location.search).to.be.empty - }) - }) - - it('cy.url() - get the current URL', function () { - // https://on.cypress.io/url - cy.url().should('eq', 'https://example.cypress.io/commands/location') - }) - }) - - context('Navigation', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io') - cy.get('.navbar-nav').contains('Commands').click() - cy.get('.dropdown-menu').contains('Navigation').click() - }) - - it('cy.go() - go back or forward in the browser\'s history', function () { - cy.location('pathname').should('include', 'navigation') - - // https://on.cypress.io/go - cy.go('back') - cy.location('pathname').should('not.include', 'navigation') - - cy.go('forward') - cy.location('pathname').should('include', 'navigation') - - // equivalent to clicking back - cy.go(-1) - cy.location('pathname').should('not.include', 'navigation') - - // equivalent to clicking forward - cy.go(1) - cy.location('pathname').should('include', 'navigation') - }) - - it('cy.reload() - reload the page', function () { - // https://on.cypress.io/reload - cy.reload() - - // reload the page without using the cache - cy.reload(true) - }) - - it('cy.visit() - visit a remote url', function () { - // Visit any sub-domain of your current domain - // https://on.cypress.io/visit - - // Pass options to the visit - cy.visit('https://example.cypress.io/commands/navigation', { - timeout: 50000, // increase total time for the visit to resolve - onBeforeLoad (contentWindow) { - // contentWindow is the remote page's window object - }, - onLoad (contentWindow) { - // contentWindow is the remote page's window object - }, - }) - }) - }) - - context('Assertions', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/assertions') - }) - - describe('Implicit Assertions', function () { - - it('.should() - make an assertion about the current subject', function () { - // https://on.cypress.io/should - cy.get('.assertion-table') - .find('tbody tr:last').should('have.class', 'success') - }) - - it('.and() - chain multiple assertions together', function () { - // https://on.cypress.io/and - cy.get('.assertions-link') - .should('have.class', 'active') - .and('have.attr', 'href') - .and('include', 'cypress.io') - }) - }) - - describe('Explicit Assertions', function () { - // https://on.cypress.io/assertions - it('expect - assert shape of an object', function () { - const person = { - name: 'Joe', - age: 20, - } - expect(person).to.have.all.keys('name', 'age') - }) - - it('expect - make an assertion about a specified subject', function () { - // We can use Chai's BDD style assertions - expect(true).to.be.true - - // Pass a function to should that can have any number - // of explicit assertions within it. - cy.get('.assertions-p').find('p') - .should(function ($p) { - // return an array of texts from all of the p's - let texts = $p.map(function (i, el) { - // https://on.cypress.io/$ - return Cypress.$(el).text() - }) - - // jquery map returns jquery object - // and .get() convert this to simple array - texts = texts.get() - - // array should have length of 3 - expect(texts).to.have.length(3) - - // set this specific subject - expect(texts).to.deep.eq([ - 'Some text from first p', - 'More text from second p', - 'And even more text from third p', - ]) - }) - }) - }) - }) - - context('Misc', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/misc') - }) - - it('.end() - end the command chain', function () { - // cy.end is useful when you want to end a chain of commands - // and force Cypress to re-query from the root element - - // https://on.cypress.io/end - cy.get('.misc-table').within(function () { - // ends the current chain and yields null - cy.contains('Cheryl').click().end() - - // queries the entire table again - cy.contains('Charles').click() - }) - }) - - it('cy.exec() - execute a system command', function () { - // cy.exec allows you to execute a system command. - // so you can take actions necessary for your test, - // but outside the scope of Cypress. - - // https://on.cypress.io/exec - cy.exec('echo Jane Lane') - .its('stdout').should('contain', 'Jane Lane') - - // we can use Cypress.platform string to - // select appropriate command - // https://on.cypress.io/platform - cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`) - - if (Cypress.platform === 'win32') { - cy.exec('print cypress.json') - .its('stderr').should('be.empty') - } else { - cy.exec('cat cypress.json') - .its('stderr').should('be.empty') - - cy.exec('pwd') - .its('code').should('eq', 0) - } - }) - - it('cy.focused() - get the DOM element that has focus', function () { - // https://on.cypress.io/focused - cy.get('.misc-form').find('#name').click() - cy.focused().should('have.id', 'name') - - cy.get('.misc-form').find('#description').click() - cy.focused().should('have.id', 'description') - }) - - it('cy.screenshot() - take a screenshot', function () { - // https://on.cypress.io/screenshot - cy.screenshot('my-image') - }) - - it('cy.wrap() - wrap an object', function () { - // https://on.cypress.io/wrap - cy.wrap({ foo: 'bar' }) - .should('have.property', 'foo') - .and('include', 'bar') - }) - }) - - context('Connectors', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/connectors') - }) - - it('.each() - iterate over an array of elements', function () { - // https://on.cypress.io/each - cy.get('.connectors-each-ul>li') - .each(function ($el, index, $list) { - console.log($el, index, $list) - }) - }) - - it('.its() - get properties on the current subject', function () { - // https://on.cypress.io/its - cy.get('.connectors-its-ul>li') - // calls the 'length' property yielding that value - .its('length') - .should('be.gt', 2) - }) - - it('.invoke() - invoke a function on the current subject', function () { - // our div is hidden in our script.js - // $('.connectors-div').hide() - - // https://on.cypress.io/invoke - cy.get('.connectors-div').should('be.hidden') - - // call the jquery method 'show' on the 'div.container' - .invoke('show') - .should('be.visible') - }) - - it('.spread() - spread an array as individual args to callback function', function () { - // https://on.cypress.io/spread - let arr = ['foo', 'bar', 'baz'] - - cy.wrap(arr).spread(function (foo, bar, baz) { - expect(foo).to.eq('foo') - expect(bar).to.eq('bar') - expect(baz).to.eq('baz') - }) - }) - - it('.then() - invoke a callback function with the current subject', function () { - // https://on.cypress.io/then - cy.get('.connectors-list>li').then(function ($lis) { - expect($lis).to.have.length(3) - expect($lis.eq(0)).to.contain('Walk the dog') - expect($lis.eq(1)).to.contain('Feed the cat') - expect($lis.eq(2)).to.contain('Write JavaScript') - }) - }) - }) - - context('Aliasing', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/aliasing') - }) - - // We alias a DOM element for use later - // We don't have to traverse to the element - // later in our code, we just reference it with @ - - it('.as() - alias a route or DOM element for later use', function () { - // this is a good use case for an alias, - // we don't want to write this long traversal again - - // https://on.cypress.io/as - cy.get('.as-table').find('tbody>tr') - .first().find('td').first().find('button').as('firstBtn') - - // maybe do some more testing here... - - // when we reference the alias, we place an - // @ in front of it's name - cy.get('@firstBtn').click() - - cy.get('@firstBtn') - .should('have.class', 'btn-success') - .and('contain', 'Changed') - }) - }) - - context('Waiting', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/waiting') - }) - // BE CAREFUL of adding unnecessary wait times. - - // https://on.cypress.io/wait - it('cy.wait() - wait for a specific amount of time', function () { - cy.get('.wait-input1').type('Wait 1000ms after typing') - cy.wait(1000) - cy.get('.wait-input2').type('Wait 1000ms after typing') - cy.wait(1000) - cy.get('.wait-input3').type('Wait 1000ms after typing') - cy.wait(1000) - }) - - // Waiting for a specific resource to resolve - // is covered within the cy.route() test below - }) - - context('Network Requests', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/network-requests') - }) - - // Manage AJAX / XHR requests in your app - - it('cy.server() - control behavior of network requests and responses', function () { - // https://on.cypress.io/server - cy.server().should(function (server) { - // the default options on server - // you can override any of these options - expect(server.delay).to.eq(0) - expect(server.method).to.eq('GET') - expect(server.status).to.eq(200) - expect(server.headers).to.be.null - expect(server.response).to.be.null - expect(server.onRequest).to.be.undefined - expect(server.onResponse).to.be.undefined - expect(server.onAbort).to.be.undefined - - // These options control the server behavior - // affecting all requests - - // pass false to disable existing route stubs - expect(server.enable).to.be.true - // forces requests that don't match your routes to 404 - expect(server.force404).to.be.false - // whitelists requests from ever being logged or stubbed - expect(server.whitelist).to.be.a('function') - }) - - cy.server({ - method: 'POST', - delay: 1000, - status: 422, - response: {}, - }) - - // any route commands will now inherit the above options - // from the server. anything we pass specifically - // to route will override the defaults though. - }) - - it('cy.request() - make an XHR request', function () { - // https://on.cypress.io/request - cy.request('https://jsonplaceholder.typicode.com/comments') - .should(function (response) { - expect(response.status).to.eq(200) - expect(response.body).to.have.length(500) - expect(response).to.have.property('headers') - expect(response).to.have.property('duration') - }) - }) - - it('cy.route() - route responses to matching requests', function () { - let message = 'whoa, this comment doesn\'t exist' - cy.server() - - // **** GET comments route **** - - // https://on.cypress.io/route - cy.route(/comments\/1/).as('getComment') - - // we have code that fetches a comment when - // the button is clicked in scripts.js - cy.get('.network-btn').click() - - // **** Wait **** - - // Wait for a specific resource to resolve - // continuing to the next command - - // https://on.cypress.io/wait - cy.wait('@getComment').its('status').should('eq', 200) - - // **** POST comment route **** - - // Specify the route to listen to method 'POST' - cy.route('POST', '/comments').as('postComment') - - // we have code that posts a comment when - // the button is clicked in scripts.js - cy.get('.network-post').click() - cy.wait('@postComment') - - // get the route - cy.get('@postComment').then(function (xhr) { - expect(xhr.requestBody).to.include('email') - expect(xhr.requestHeaders).to.have.property('Content-Type') - expect(xhr.responseBody).to.have.property('name', 'Using POST in cy.route()') - }) - - // **** Stubbed PUT comment route **** - cy.route({ - method: 'PUT', - url: /comments\/\d+/, - status: 404, - response: { error: message }, - delay: 500, - }).as('putComment') - - // we have code that puts a comment when - // the button is clicked in scripts.js - cy.get('.network-put').click() - - cy.wait('@putComment') - - // our 404 statusCode logic in scripts.js executed - cy.get('.network-put-comment').should('contain', message) - }) - }) - - context('Files', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/files') - }) - it('cy.fixture() - load a fixture', function () { - // Instead of writing a response inline you can - // connect a response with a fixture file - // located in fixtures folder. - - cy.server() - - // https://on.cypress.io/fixture - cy.fixture('example.json').as('comment') - - cy.route(/comments/, '@comment').as('getComment') - - // we have code that gets a comment when - // the button is clicked in scripts.js - cy.get('.fixture-btn').click() - - cy.wait('@getComment').its('responseBody') - .should('have.property', 'name') - .and('include', 'Using fixtures to represent data') - - // you can also just write the fixture in the route - cy.route(/comments/, 'fixture:example.json').as('getComment') - - // we have code that gets a comment when - // the button is clicked in scripts.js - cy.get('.fixture-btn').click() - - cy.wait('@getComment').its('responseBody') - .should('have.property', 'name') - .and('include', 'Using fixtures to represent data') - - // or write fx to represent fixture - // by default it assumes it's .json - cy.route(/comments/, 'fx:example').as('getComment') - - // we have code that gets a comment when - // the button is clicked in scripts.js - cy.get('.fixture-btn').click() - - cy.wait('@getComment').its('responseBody') - .should('have.property', 'name') - .and('include', 'Using fixtures to represent data') - }) - - it('cy.readFile() - read a files contents', function () { - // You can read a file and yield its contents - // The filePath is relative to your project's root. - - // https://on.cypress.io/readfile - cy.readFile('cypress.json').then(function (json) { - expect(json).to.be.an('object') - }) - - }) - - it('cy.writeFile() - write to a file', function () { - // You can write to a file with the specified contents - - // Use a response from a request to automatically - // generate a fixture file for use later - cy.request('https://jsonplaceholder.typicode.com/users') - .then(function (response) { - // https://on.cypress.io/writefile - cy.writeFile('cypress/fixtures/users.json', response.body) - }) - cy.fixture('users').should(function (users) { - expect(users[0].name).to.exist - }) - - // JavaScript arrays and objects are stringified and formatted into text. - cy.writeFile('cypress/fixtures/profile.json', { - id: 8739, - name: 'Jane', - email: 'jane@example.com', - }) - - cy.fixture('profile').should(function (profile) { - expect(profile.name).to.eq('Jane') - }) - }) - }) - - context('Local Storage', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/commands/local-storage') - }) - // Although local storage is automatically cleared - // to maintain a clean state in between tests - // sometimes we need to clear the local storage manually - - it('cy.clearLocalStorage() - clear all data in local storage', function () { - // https://on.cypress.io/clearlocalstorage - cy.get('.ls-btn').click().should(function () { - expect(localStorage.getItem('prop1')).to.eq('red') - expect(localStorage.getItem('prop2')).to.eq('blue') - expect(localStorage.getItem('prop3')).to.eq('magenta') - }) - - // clearLocalStorage() yields the localStorage object - cy.clearLocalStorage().should(function (ls) { - expect(ls.getItem('prop1')).to.be.null - expect(ls.getItem('prop2')).to.be.null - expect(ls.getItem('prop3')).to.be.null - }) - - // **** Clear key matching string in Local Storage **** - cy.get('.ls-btn').click().should(function () { - expect(localStorage.getItem('prop1')).to.eq('red') - expect(localStorage.getItem('prop2')).to.eq('blue') - expect(localStorage.getItem('prop3')).to.eq('magenta') - }) - - cy.clearLocalStorage('prop1').should(function (ls) { - expect(ls.getItem('prop1')).to.be.null - expect(ls.getItem('prop2')).to.eq('blue') - expect(ls.getItem('prop3')).to.eq('magenta') - }) - - // **** Clear key's matching regex in Local Storage **** - cy.get('.ls-btn').click().should(function () { - expect(localStorage.getItem('prop1')).to.eq('red') - expect(localStorage.getItem('prop2')).to.eq('blue') - expect(localStorage.getItem('prop3')).to.eq('magenta') - }) - - cy.clearLocalStorage(/prop1|2/).should(function (ls) { - expect(ls.getItem('prop1')).to.be.null - expect(ls.getItem('prop2')).to.be.null - expect(ls.getItem('prop3')).to.eq('magenta') - }) - }) - }) - - context('Cookies', function () { - beforeEach(function () { - Cypress.Cookies.debug(true) - - cy.visit('https://example.cypress.io/commands/cookies') - - // clear cookies again after visiting to remove - // any 3rd party cookies picked up such as cloudflare - cy.clearCookies() - }) - - it('cy.getCookie() - get a browser cookie', function () { - // https://on.cypress.io/getcookie - cy.get('#getCookie .set-a-cookie').click() - - // cy.getCookie() yields a cookie object - cy.getCookie('token').should('have.property', 'value', '123ABC') - }) - - it('cy.getCookies() - get browser cookies', function () { - // https://on.cypress.io/getcookies - cy.getCookies().should('be.empty') - - cy.get('#getCookies .set-a-cookie').click() - - // cy.getCookies() yields an array of cookies - cy.getCookies().should('have.length', 1).should(function (cookies) { - - // each cookie has these properties - expect(cookies[0]).to.have.property('name', 'token') - expect(cookies[0]).to.have.property('value', '123ABC') - expect(cookies[0]).to.have.property('httpOnly', false) - expect(cookies[0]).to.have.property('secure', false) - expect(cookies[0]).to.have.property('domain') - expect(cookies[0]).to.have.property('path') - }) - }) - - it('cy.setCookie() - set a browser cookie', function () { - // https://on.cypress.io/setcookie - cy.getCookies().should('be.empty') - - cy.setCookie('foo', 'bar') - - // cy.getCookie() yields a cookie object - cy.getCookie('foo').should('have.property', 'value', 'bar') - }) - - it('cy.clearCookie() - clear a browser cookie', function () { - // https://on.cypress.io/clearcookie - cy.getCookie('token').should('be.null') - - cy.get('#clearCookie .set-a-cookie').click() - - cy.getCookie('token').should('have.property', 'value', '123ABC') - - // cy.clearCookies() yields null - cy.clearCookie('token').should('be.null') - - cy.getCookie('token').should('be.null') - }) - - it('cy.clearCookies() - clear browser cookies', function () { - // https://on.cypress.io/clearcookies - cy.getCookies().should('be.empty') - - cy.get('#clearCookies .set-a-cookie').click() - - cy.getCookies().should('have.length', 1) - - // cy.clearCookies() yields null - cy.clearCookies() - - cy.getCookies().should('be.empty') - }) - }) - - context('Spies, Stubs, and Clock', function () { - it('cy.spy() - wrap a method in a spy', function () { - // https://on.cypress.io/spy - cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') - - let obj = { - foo () {}, - } - - let spy = cy.spy(obj, 'foo').as('anyArgs') - - obj.foo() - - expect(spy).to.be.called - - }) - - it('cy.stub() - create a stub and/or replace a function with a stub', function () { - // https://on.cypress.io/stub - cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') - - let obj = { - foo () {}, - } - - let stub = cy.stub(obj, 'foo').as('foo') - - obj.foo('foo', 'bar') - - expect(stub).to.be.called - - }) - - it('cy.clock() - control time in the browser', function () { - // create the date in UTC so its always the same - // no matter what local timezone the browser is running in - let now = new Date(Date.UTC(2017, 2, 14)).getTime() - - // https://on.cypress.io/clock - cy.clock(now) - cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') - cy.get('#clock-div').click() - .should('have.text', '1489449600') - }) - - it('cy.tick() - move time in the browser', function () { - // create the date in UTC so its always the same - // no matter what local timezone the browser is running in - let now = new Date(Date.UTC(2017, 2, 14)).getTime() - - // https://on.cypress.io/tick - cy.clock(now) - cy.visit('https://example.cypress.io/commands/spies-stubs-clocks') - cy.get('#tick-div').click() - .should('have.text', '1489449600') - cy.tick(10000) // 10 seconds passed - cy.get('#tick-div').click() - .should('have.text', '1489449610') - }) - }) - - context('Utilities', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/utilities') - }) - - it('Cypress._.method() - call a lodash method', function () { - // use the _.chain, _.map, _.take, and _.value functions - // https://on.cypress.io/_ - cy.request('https://jsonplaceholder.typicode.com/users') - .then(function (response) { - let ids = Cypress._.chain(response.body).map('id').take(3).value() - - expect(ids).to.deep.eq([1, 2, 3]) - }) - }) - - it('Cypress.$(selector) - call a jQuery method', function () { - // https://on.cypress.io/$ - let $li = Cypress.$('.utility-jquery li:first') - - cy.wrap($li) - .should('not.have.class', 'active') - .click() - .should('have.class', 'active') - }) - - it('Cypress.moment() - format or parse dates using a moment method', function () { - // use moment's format function - // https://on.cypress.io/cypress-moment - let time = Cypress.moment().utc('2014-04-25T19:38:53.196Z').format('h:mm A') - - cy.get('.utility-moment').contains('3:38 PM') - .should('have.class', 'badge') - }) - - it('Cypress.Blob.method() - blob utilities and base64 string conversion', function () { - cy.get('.utility-blob').then(function ($div) { - // https://on.cypress.io/blob - // https://github.com/nolanlawson/blob-util#imgSrcToDataURL - // get the dataUrl string for the javascript-logo - return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous') - .then(function (dataUrl) { - // create an <img> element and set its src to the dataUrl - let img = Cypress.$('<img />', { src: dataUrl }) - // need to explicitly return cy here since we are initially returning - // the Cypress.Blob.imgSrcToDataURL promise to our test - // append the image - $div.append(img) - - cy.get('.utility-blob img').click() - .should('have.attr', 'src', dataUrl) - }) - }) - }) - - it('new Cypress.Promise(function) - instantiate a bluebird promise', function () { - // https://on.cypress.io/promise - let waited = false - - function waitOneSecond () { - // return a promise that resolves after 1 second - return new Cypress.Promise(function (resolve, reject) { - setTimeout(function () { - // set waited to true - waited = true - - // resolve with 'foo' string - resolve('foo') - }, 1000) - }) - } - - cy.then(function () { - // return a promise to cy.then() that - // is awaited until it resolves - return waitOneSecond().then(function (str) { - expect(str).to.eq('foo') - expect(waited).to.be.true - }) - }) - }) - }) - - - context('Cypress.config()', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/cypress-api/config') - }) - - it('Cypress.config() - get and set configuration options', function () { - // https://on.cypress.io/config - let myConfig = Cypress.config() - - expect(myConfig).to.have.property('animationDistanceThreshold', 5) - expect(myConfig).to.have.property('baseUrl', null) - expect(myConfig).to.have.property('defaultCommandTimeout', 4000) - expect(myConfig).to.have.property('requestTimeout', 5000) - expect(myConfig).to.have.property('responseTimeout', 30000) - expect(myConfig).to.have.property('viewportHeight', 660) - expect(myConfig).to.have.property('viewportWidth', 1000) - expect(myConfig).to.have.property('pageLoadTimeout', 60000) - expect(myConfig).to.have.property('waitForAnimations', true) - - expect(Cypress.config('pageLoadTimeout')).to.eq(60000) - - // this will change the config for the rest of your tests! - Cypress.config('pageLoadTimeout', 20000) - - expect(Cypress.config('pageLoadTimeout')).to.eq(20000) - - Cypress.config('pageLoadTimeout', 60000) - }) - }) - - context('Cypress.env()', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/cypress-api/env') - }) - - // We can set environment variables for highly dynamic values - - // https://on.cypress.io/environment-variables - it('Cypress.env() - get environment variables', function () { - // https://on.cypress.io/env - // set multiple environment variables - Cypress.env({ - host: 'veronica.dev.local', - api_server: 'http://localhost:8888/v1/', - }) - - // get environment variable - expect(Cypress.env('host')).to.eq('veronica.dev.local') - - // set environment variable - Cypress.env('api_server', 'http://localhost:8888/v2/') - expect(Cypress.env('api_server')).to.eq('http://localhost:8888/v2/') - - // get all environment variable - expect(Cypress.env()).to.have.property('host', 'veronica.dev.local') - expect(Cypress.env()).to.have.property('api_server', 'http://localhost:8888/v2/') - }) - }) - - context('Cypress.Cookies', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/cypress-api/cookies') - }) - - // https://on.cypress.io/cookies - it('Cypress.Cookies.debug() - enable or disable debugging', function () { - Cypress.Cookies.debug(true) - - // Cypress will now log in the console when - // cookies are set or cleared - cy.setCookie('fakeCookie', '123ABC') - cy.clearCookie('fakeCookie') - cy.setCookie('fakeCookie', '123ABC') - cy.clearCookie('fakeCookie') - cy.setCookie('fakeCookie', '123ABC') - }) - - it('Cypress.Cookies.preserveOnce() - preserve cookies by key', function () { - // normally cookies are reset after each test - cy.getCookie('fakeCookie').should('not.be.ok') - - // preserving a cookie will not clear it when - // the next test starts - cy.setCookie('lastCookie', '789XYZ') - Cypress.Cookies.preserveOnce('lastCookie') - }) - - it('Cypress.Cookies.defaults() - set defaults for all cookies', function () { - // now any cookie with the name 'session_id' will - // not be cleared before each new test runs - Cypress.Cookies.defaults({ - whitelist: 'session_id', - }) - }) - }) - - context('Cypress.dom', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/cypress-api/dom') - }) - - // https://on.cypress.io/dom - it('Cypress.dom.isHidden() - determine if a DOM element is hidden', function () { - let hiddenP = Cypress.$('.dom-p p.hidden').get(0) - let visibleP = Cypress.$('.dom-p p.visible').get(0) - - // our first paragraph has css class 'hidden' - expect(Cypress.dom.isHidden(hiddenP)).to.be.true - expect(Cypress.dom.isHidden(visibleP)).to.be.false - }) - }) - - context('Cypress.Server', function () { - beforeEach(function () { - cy.visit('https://example.cypress.io/cypress-api/server') - }) - - // Permanently override server options for - // all instances of cy.server() - - // https://on.cypress.io/cypress-server - it('Cypress.Server.defaults() - change default config of server', function () { - Cypress.Server.defaults({ - delay: 0, - force404: false, - whitelist (xhr) { - // handle custom logic for whitelisting - }, - }) - }) - }) -}) diff --git a/cypress/integration/connection-notify.js b/cypress/integration/connection-notify.js deleted file mode 100644 index ecae0788c..000000000 --- a/cypress/integration/connection-notify.js +++ /dev/null @@ -1,12 +0,0 @@ -describe('Connection notification', function() { - beforeEach(function() { - cy.visit(Cypress.env('BS_URL')); - }); - it('should flash Connected message', function() { - cy.wait(500); - cy.get('#__bs_notify__').should(function($elems) { - expect($elems.length).to.equal(1); - expect($elems.text()).to.equal('Browsersync: connected'); - }); - }); -}); diff --git a/cypress/integration/css-console-notify.js b/cypress/integration/css-console-notify.js deleted file mode 100644 index 9122f5604..000000000 --- a/cypress/integration/css-console-notify.js +++ /dev/null @@ -1,26 +0,0 @@ -describe('CSS console notification', function() { - beforeEach(function() { - cy.visit(Cypress.env('BS_URL')); - }); - it('should log message when css injected', function() { - cy.window().then((win) => { - const spy = cy.spy(win.console, "log"); - cy.exec('touch packages/browser-sync/test/fixtures/**/style.css'); - cy.wait(1000).then(() => { - expect(spy.getCall(0).args.slice(-1)[0]).to.equal('[LinkReplace] style.css'); - }) - }); - }); - it('should log 2 messages when 2 css files injected', function() { - cy.window().then((win) => { - const spy = cy.spy(win.console, "log"); - cy.exec('touch packages/browser-sync/test/fixtures/**/*.css'); - cy.wait(1000).then(() => { - expect(spy.callCount).to.equal(2); - const calls = new Set([spy.getCall(0).args.slice(-1)[0], spy.getCall(1).args.slice(-1)[0]]); - expect(calls.has('[LinkReplace] style.css')).to.be.true; - expect(calls.has('[LinkReplace] stylesheet.css')).to.be.true; - }) - }); - }); -}); diff --git a/cypress/integration/css-overlay-notify.js b/cypress/integration/css-overlay-notify.js deleted file mode 100644 index f29e02226..000000000 --- a/cypress/integration/css-overlay-notify.js +++ /dev/null @@ -1,13 +0,0 @@ -describe('CSS overlay notification', function() { - beforeEach(function() { - cy.visit(Cypress.env('BS_URL')); - }); - it('should flash messages when css injected', function() { - cy.exec('touch packages/browser-sync/test/fixtures/**/style.css'); - cy.wait(500); - cy.get('#__bs_notify__').should(function($elems) { - expect($elems.length).to.equal(1); - expect($elems.text()).to.equal('[LinkReplace] style.css'); - }); - }); -}); diff --git a/cypress/integration/file-watching-ignore.js b/cypress/integration/file-watching-ignore.js deleted file mode 100644 index 9c4db909f..000000000 --- a/cypress/integration/file-watching-ignore.js +++ /dev/null @@ -1,14 +0,0 @@ -describe('Watching folders', function() { - context('files option', function () { - beforeEach(function () { - cy.visit(Cypress.env('BS_URL') + '/bower.html'); - }); - it('should reload single <link>', function () { - cy.exec('touch packages/browser-sync/test/fixtures/bower_components/app.css'); - cy.get('[id="css-style"]').should($link => { - const url = new URL($link.attr('href')); - expect(url.search).to.contain('?browsersync='); - }); - }); - }); -}); \ No newline at end of file diff --git a/cypress/integration/logPrefix.js b/cypress/integration/logPrefix.js deleted file mode 100644 index 3a466c882..000000000 --- a/cypress/integration/logPrefix.js +++ /dev/null @@ -1,22 +0,0 @@ -describe('Connection notification (with logPrefix)', function() { - beforeEach(function() { - cy.visit(Cypress.env('BS_URL')); - }); - it('should flash correct Connected message', function() { - cy.wait(500); - cy.get('#__bs_notify__').should(function($elems) { - expect($elems.length).to.equal(1); - expect($elems.text()).to.equal('WSK: connected'); - }); - }); - it('should log prefixed message when css is injected', function() { - cy.window().then((win) => { - const spy = cy.spy(win.console, "log"); - cy.exec('touch packages/browser-sync/test/fixtures/**/style.css'); - cy.wait(1000).then(() => { - expect(spy.getCall(0).args.slice(-1)[0]).to.equal('[LinkReplace] style.css'); - expect(spy.getCall(0).args.indexOf('WSK') > -1).to.be.true; - }) - }); - }); -}); diff --git a/cypress/integration/no-notify.js b/cypress/integration/no-notify.js deleted file mode 100644 index 504f67924..000000000 --- a/cypress/integration/no-notify.js +++ /dev/null @@ -1,14 +0,0 @@ -describe('disabled notification', function() { - beforeEach(function() { - cy.visit(Cypress.env('BS_URL')); - }); - it('should not flash Connected message', function() { - cy.wait(500); - cy.get('#__bs_notify__').should('have.length', 0); - }); - it('should not flash messages when css injected', function() { - cy.exec('touch packages/browser-sync/test/fixtures/**/style.css'); - cy.wait(500); - cy.get('#__bs_notify__').should('have.length', 0); - }); -}); diff --git a/cypress/integration/ui-remote-debug.js b/cypress/integration/ui-remote-debug.js deleted file mode 100644 index d70e18b4d..000000000 --- a/cypress/integration/ui-remote-debug.js +++ /dev/null @@ -1,28 +0,0 @@ -describe('UI', function () { - context('Remote Debugger', function () { - it('adds an element, in the way the UI does', function () { - cy.visit(Cypress.env('BS_URL')); - cy.get('#__bs_notify__').should('have.length', 1); - cy.request('POST', `${Cypress.env('BS_URL')}/__browser_sync__`, - JSON.stringify(["ui:element:add", - { - "src": "/browser-sync/pesticide.css", - "active": true, - "hidden": "", - "name": "pesticide", - "tagline": "Add simple CSS outlines to all elements. (powered by <span style='text-decoration: line-through'>Pesticide.io</span>)", - "context": "remote-debug", - "served": true, - "title": "CSS Outlining", - "type": "css", - "id": "__browser-sync-pesticide__", - "file": "/Users/shakyshane/sites/oss/browser-sync/node_modules/browser-sync-ui/lib/plugins/remote-debug/css/pesticide.min.css" - } - ]) - ).then(res => { - console.log(res); - }); - cy.get('[id="__browser-sync-pesticide__"]').should('have.length', 1); - }); - }); -}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js deleted file mode 100644 index fd170fba6..000000000 --- a/cypress/plugins/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -module.exports = (on, config) => { - // `on` is used to hook into various events Cypress emits - // `config` is the resolved Cypress config -} diff --git a/cypress/setup/bs-cli.js b/cypress/setup/bs-cli.js deleted file mode 100644 index 660a2773d..000000000 --- a/cypress/setup/bs-cli.js +++ /dev/null @@ -1,46 +0,0 @@ -const cypress = require('cypress'); -const exec = require('child_process'); -const assert = require('assert'); -const {Observable} = require('rxjs/Observable'); - -module.exports = function(opts) { - - assert.ok(Array.isArray(opts.args), '`args` should be an array of strings'); - assert.ok(opts.args.every(arg => typeof arg === 'string'), '`args` should contain only strings'); - - return Observable.create(obs => { - const ls = exec.spawn('node', [ - 'dist/bin', - ...opts.args - ]); - - ls.stdout.once('data', (data) => { - try { - const parsed = JSON.parse(String(data)); - const {urls} = parsed["service:running"].options; - - return cypress.run({ - spec: opts.spec, - env: `BS_URL=${urls.local}` - }) - .then((results) => { - // stop your server when it's complete - if (results.failures > 0) { - return obs.error(new Error('failed!')); - } - obs.complete(); - }) - } catch (e) { - console.error('Parsing Browsersync output failed', e); - return obs.error(new Error('failed!')); - } - }); - ls.stderr.on('data', (data) => { - console.log(data); - return obs.error(new Error('failed!')); - }); - return () => { - ls.kill(); - } - }); -}; diff --git a/cypress/setup/bs.js b/cypress/setup/bs.js deleted file mode 100644 index 9a3e7c4ac..000000000 --- a/cypress/setup/bs.js +++ /dev/null @@ -1,35 +0,0 @@ -const cypress = require('cypress'); -const exec = require('child_process'); -const assert = require('assert'); -const {join} = require('path'); -const {Observable} = require('rxjs'); - -module.exports = function(opts, ctx) { - - assert.ok(typeof opts.config === 'string', '`opts.config` should be a string'); - assert.ok(typeof opts.spec === 'string', '`opts.spec` should be a string'); - assert.ok((opts.action === 'run' || opts.action === 'open'), '`action` should be either run or open'); - - const json = require(join(ctx.config.cwd, opts.config)); - - return Observable.create(obs => { - const bs = require('../../packages/browser-sync').create(); - const instance = bs.init(json, function(err, bs) { - if (err) { - return obs.error(err); - } - return cypress[opts.action]({ - spec: opts.spec, - env: `BS_URL=${bs.options.getIn(['urls', 'local'])},BS_UI_URL=${bs.options.getIn(['urls', 'ui'])}` - }) - .then((results) => { - // stop your server when it's complete - if (results.failures > 0) { - return obs.error(new Error('Errors occurred')); - } - instance.cleanup(); - obs.complete(); - }) - }); - }); -}; diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index c1f5a772e..000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This is will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index d68db96df..000000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/examples/basic/run.js b/examples/basic/run.js index c0685cf70..354625f95 100644 --- a/examples/basic/run.js +++ b/examples/basic/run.js @@ -6,7 +6,6 @@ bs.init( { server: serverDir, open: false, - notify: false, watch: true, online: false }, diff --git a/tests/examples/basic/basic.spec.ts b/tests/examples/basic/basic.spec.ts index a12dcc120..e51bea607 100644 --- a/tests/examples/basic/basic.spec.ts +++ b/tests/examples/basic/basic.spec.ts @@ -152,3 +152,36 @@ test.describe("basic", () => { expect(style).toContain("?browsersync"); }); }); + +test.describe("UI", () => { + test("remote debugger", async ({ context, page, bs }) => { + await page.goto(bs.url); + const request = makesRequestIn(page, { + matches: { + pathname: "/browser-sync/pesticide.css" + } + }); + + // open the UI + const ui = await context.newPage(); + await ui.goto(bs.uiUrl); + await ui.getByRole("button", { name: "Remote Debug" }).click(); + await ui + .locator("label") + .first() + .click(); + + // back to the main page + await page.bringToFront(); + + // ensure the CSS file was requested + await request; + }); +}); + +test.describe("Overlays", () => { + test("should flash Connected message", async ({ context, page, bs }) => { + await page.goto(bs.url); + await page.locator("#__bs_notify__").waitFor({ timeout: 5000 }); + }); +}); diff --git a/tests/utils.ts b/tests/utils.ts index 99466b45c..83d193160 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -8,7 +8,8 @@ const messageSchema = z.discriminatedUnion("kind", [ z.object({ kind: z.literal("ready"), urls: z.object({ - local: z.string() + local: z.string(), + ui: z.string() }), cwd: z.string() }) @@ -22,6 +23,7 @@ interface NextArgs { export const test = base.extend<{ bs: { url: string; + uiUrl: string; child: any; stdout: string[]; touch: (path: string) => void; @@ -86,6 +88,7 @@ export const test = base.extend<{ await use({ url: msg.urls.local, + uiUrl: msg.urls.ui, child, stdout, touch: (path: string) => {