diff --git a/app/commands/actions.html b/app/commands/actions.html index 403bd4c87..b3a904aff 100644 --- a/app/commands/actions.html +++ b/app/commands/actions.html @@ -74,28 +74,28 @@

Actions

.type()

To type into a DOM element, use the .type() command.

-
cy.get('.action-email')
-  .type('fake@email.com').should('have.value', 'fake@email.com')
+          
cy.get('.action-email').type('fake@email.com')
+cy.get('.action-email').should('have.value', 'fake@email.com')
 
-  // .type() with special character sequences
-  .type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
-  .type('{del}{selectall}{backspace}')
+// .type() with special character sequences
+cy.get('.action-email').type('{leftarrow}{rightarrow}{uparrow}{downarrow}')
+cy.get('.action-email').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}')
+// .type() with key modifiers
+cy.get('.action-email').type('{alt}{option}') //these are equivalent
+cy.get('.action-email').type('{ctrl}{control}') //these are equivalent
+cy.get('.action-email').type('{meta}{command}{cmd}') //these are equivalent
+cy.get('.action-email').type('{shift}')
 
-  // Delay each keypress by 0.1 sec
-  .type('slow.typing@email.com', { delay: 100 })
-  .should('have.value', 'slow.typing@email.com')
+// Delay each keypress by 0.1 sec
+cy.get('.action-email').type('slow.typing@email.com', { delay: 100 })
+cy.get('.action-email').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')
+cy.get('.action-disabled').should('have.value', 'disabled error checking')
@@ -118,7 +118,7 @@

.type()

.focus()

To focus on a DOM element, use the .focus() command.

cy.get('.action-focus').focus()
-  .should('have.class', 'focus')
+cy.get('.action-focus').should('have.class', 'focus')
   .prev().should('have.attr', 'style', 'color: orange;')
@@ -137,9 +137,11 @@

.focus()

.blur()

To blur on a DOM element, use the .blur() command.

-
cy.get('.action-blur').type('About to blur').blur()
-  .should('have.class', 'error')
-  .prev().should('have.attr', 'style', 'color: red;')
+
cy.get('.action-blur').type('About to blur')
+cy.get('.action-blur').blur()
+cy.get('.action-blur').should('have.class', 'error')
+  .prev().should('have.attr', 'style', 'color: red;')
+          
@@ -158,9 +160,9 @@

.blur()

.clear()

To clear on a DOM element, use the .clear() command.

cy.get('.action-clear').type('Clear this text')
-  .should('have.value', 'Clear this text')
-  .clear()
-  .should('have.value', '')
+cy.get('.action-clear').should('have.value', 'Clear this text') +cy.get('.action-clear').clear() +cy.get('.action-clear').should('have.value', '')
@@ -180,8 +182,9 @@

.submit()

To submit a form, use the cy.submit() command.

cy.get('.action-form')
   .find('[type="text"]').type('HALFOFF')
+      
 cy.get('.action-form').submit()
-  .next().should('contain', 'Your form has been submitted!')
+cy.get('.action-form').next().should('contain', 'Your form has been submitted!')
@@ -202,6 +205,19 @@

.click()

To click a DOM element, use the .click() command.

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()
 
@@ -214,16 +230,17 @@ 

.click()

cy.get('#action-canvas').click('bottom') cy.get('#action-canvas').click('bottomRight') -// .click() accepts a an x and y coordinate +// .click() accepts an x and y coordinate // that controls where the click occurs :) + cy.get('#action-canvas') - .click(80, 75) - .click(170, 75) - .click(80, 165) - .click(100, 185) - .click(125, 190) - .click(150, 185) - .click(170, 165) +cy.get('#action-canvas').click(80, 75) // click 80px on x coord and 75px on y coord +cy.get('#action-canvas').click(170, 75) +cy.get('#action-canvas').click(80, 165) +cy.get('#action-canvas').click(100, 185) +cy.get('#action-canvas').click(125, 190) +cy.get('#action-canvas').click(150, 185) +cy.get('#action-canvas').click(170, 165) // click multiple elements by passing multiple: true cy.get('.action-labels>.label').click({ multiple: true }) @@ -264,7 +281,10 @@
Canvas to Illustrate Click Positions

.dblclick()

To double click a DOM element, use the .dblclick() command.

-
cy.get('.action-div').dblclick().should('not.be.visible')
+          
// Our app has a listener on 'dblclick' event in our 'scripts.js'
+// that hides the div and shows an input on double click
+cy.get('.action-div').dblclick()
+cy.get('.action-div').should('not.be.visible')
 cy.get('.action-input-hidden').should('be.visible')
@@ -284,7 +304,10 @@

.dblclick()

.rightclick()

To right click a DOM element, use the .rightclick() command.

-
cy.get('.rightclick-action-div').rightclick().should('not.be.visible')
+          
// Our app has a listener on 'contextmenu' event in our 'scripts.js'
+// that hides the div and shows an input on right click
+cy.get('.rightclick-action-div').rightclick()
+cy.get('.rightclick-action-div').should('not.be.visible')
 cy.get('.rightclick-action-input-hidden').should('be.visible')
@@ -307,26 +330,26 @@

.check()

To check a checkbox or radio, use the .check() command.

// By default, .check() will check all
 // matching checkbox or radio elements in succession, one after another
-cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]')
-  .check().should('be.checked')
+cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').check()
+cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]').should('be.checked')
 
-cy.get('.action-radios [type="radio"]').not('[disabled]')
-  .check().should('be.checked')
+cy.get('.action-radios [type="radio"]').not('[disabled]').check()
+cy.get('.action-radios [type="radio"]').not('[disabled]').should('be.checked')
 
 // .check() accepts a value argument
-cy.get('.action-radios [type="radio"]')
-  .check('radio1').should('be.checked')
+cy.get('.action-radios [type="radio"]').check('radio1')
+cy.get('.action-radios [type="radio"]').should('be.checked')
 
 // .check() accepts an array of values
-cy.get('.action-multiple-checkboxes [type="checkbox"]')
-  .check(['checkbox1', 'checkbox2']).should('be.checked')
+cy.get('.action-multiple-checkboxes [type="checkbox"]').check(['checkbox1', 'checkbox2'])
+cy.get('.action-multiple-checkboxes [type="checkbox"]').should('be.checked')
 
 // Ignore error checking prior to checking
-cy.get('.action-checkboxes [disabled]')
-  .check({ force: true }).should('be.checked')
+cy.get('.action-checkboxes [disabled]').check({ force: true })
+cy.get('.action-checkboxes [disabled]').should('be.checked')
 
-cy.get('.action-radios [type="radio"]')
-  .check('radio3', { force: true }).should('be.checked')
+cy.get('.action-radios [type="radio"]').check('radio3', { force: true }) +cy.get('.action-radios [type="radio"]').should('be.checked')
@@ -408,21 +431,32 @@

.uncheck()

// checkbox elements in succession, one after another cy.get('.action-check [type="checkbox"]') .not('[disabled]') - .uncheck().should('not.be.checked') + .uncheck() +cy.get('.action-check [type="checkbox"]') + .not('[disabled]') + .should('not.be.checked') // .uncheck() accepts a value argument cy.get('.action-check [type="checkbox"]') .check('checkbox1') - .uncheck('checkbox1').should('not.be.checked') +cy.get('.action-check [type="checkbox"]') + .uncheck('checkbox1') +cy.get('.action-check [type="checkbox"][value="checkbox1"]') + .should('not.be.checked') // .uncheck() accepts an array of values cy.get('.action-check [type="checkbox"]') .check(['checkbox1', 'checkbox3']) - .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') +cy.get('.action-check [type="checkbox"]') + .uncheck(['checkbox1', 'checkbox3']) +cy.get('.action-check [type="checkbox"][value="checkbox1"]') + .should('not.be.checked') +cy.get('.action-check [type="checkbox"][value="checkbox3"]') + .should('not.be.checked') // Ignore error checking prior to unchecking -cy.get('.action-check [disabled]') - .uncheck({ force: true }).should('not.be.checked')
+cy.get('.action-check [disabled]').uncheck({ force: true }) +cy.get('.action-check [disabled]').should('not.be.checked')
@@ -466,19 +500,23 @@

.select()

cy.get('.action-select-multiple') .select(['apples', 'oranges', 'bananas']) +cy.get('.action-select-multiple') // when getting multiple values, invoke "val" method first .invoke('val') .should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas']) // Select option(s) with matching value cy.get('.action-select').select('fr-bananas') +cy.get('.action-select') // can attach an assertion right away to the element .should('have.value', 'fr-bananas') cy.get('.action-select-multiple') .select(['fr-apples', 'fr-oranges', 'fr-bananas']) +cy.get('.action-select-multiple') .invoke('val') .should('deep.equal', ['fr-apples', 'fr-oranges', 'fr-bananas']) + // assert the selected values include oranges cy.get('.action-select-multiple') .invoke('val').should('include', 'fr-oranges') @@ -507,11 +545,16 @@

.select()

.scrollIntoView()

To scroll an element into view, use the .scrollintoview() command.

-
cy.get('#scroll-horizontal button')
+          
// 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()
+cy.get('#scroll-horizontal button')
   .should('be.visible')
 
 cy.get('#scroll-vertical button')
@@ -519,6 +562,7 @@ 

.scrollIn // Cypress handles the scroll direction needed cy.get('#scroll-vertical button').scrollIntoView() +cy.get('#scroll-vertical button') .should('be.visible') cy.get('#scroll-both button') @@ -526,6 +570,7 @@

.scrollIn // Cypress knows to scroll to the right and down cy.get('#scroll-both button').scrollIntoView() +cy.get('#scroll-both button') .should('be.visible')

@@ -558,7 +603,20 @@

.scrollIn

cy.scrollTo()

To scroll the window or a scrollable element to a specific position, use the cy.scrollTo() command.

-
// if you chain .scrollTo() off of cy, we will
+          
// 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')
 
@@ -679,9 +737,17 @@ 

cy.scrollTo()

.trigger()

To trigger an event on a DOM element, use the .trigger() command.

-
cy.get('.trigger-input-range')
+          
// To interact with a range input (slider)
+// we need to set its value & trigger the
+// event to signal it changed
+
+// Here, we invoke jQuery's val() method to set
+// the value and trigger the 'change' event
+cy.get('.trigger-input-range')
   .invoke('val', 25)
+cy.get('.trigger-input-range')
   .trigger('change')
+cy.get('.trigger-input-range')
   .get('input[type=range]').siblings('p')
   .should('have.text', '25')
diff --git a/app/commands/cookies.html b/app/commands/cookies.html index 20c1e71c8..b95a8a126 100644 --- a/app/commands/cookies.html +++ b/app/commands/cookies.html @@ -188,7 +188,7 @@

cy.clearCookie( cy.getCookie('token').should('have.property', 'value', '123ABC') // cy.clearCookies() yields null -cy.clearCookie('token').should('be.null') +cy.clearCookie('token') cy.getCookie('token').should('be.null')

diff --git a/app/commands/misc.html b/app/commands/misc.html index e720450e3..b3881da88 100644 --- a/app/commands/misc.html +++ b/app/commands/misc.html @@ -70,45 +70,6 @@

Misc

- -
-

.end()

-

To end the command chain, use the .end() command.

-
// cy.end is useful when you want to end a chain of commands
-// and force Cypress to re-query from the root element
-cy.get('.misc-table').within(() => {
-  // ends the current chain and yields null
-  cy.contains('Cheryl').click().end()
-
-  // queries the entire table again
-  cy.contains('Charles').click()
-})
-
-
-
- - - - - - - - - - - - - - - - - -
Table
User: Cheryl
User: Charles
User: Darryl
-
-
- -

-

cy.exec()

To execute a system command, use the cy.exec() command.

diff --git a/app/commands/spies-stubs-clocks.html b/app/commands/spies-stubs-clocks.html index 42b091526..a24154e93 100644 --- a/app/commands/spies-stubs-clocks.html +++ b/app/commands/spies-stubs-clocks.html @@ -135,6 +135,7 @@

cy.clock()

cy.clock(now) cy.visit('http://localhost:8080/commands/spies-stubs-clocks') cy.get('#clock-div').click() +cy.get('#clock-div') .should('have.text', '1489449600')
@@ -157,9 +158,11 @@

cy.tick()

cy.clock(now) cy.visit('http://localhost:8080/commands/spies-stubs-clocks') cy.get('#tick-div').click() +cy.get('#tick-div') .should('have.text', '1489449600') cy.tick(10000) // 10 seconds passed cy.get('#tick-div').click() +cy.get('#tick-div') .should('have.text', '1489449610')
diff --git a/app/commands/storage.html b/app/commands/storage.html index 4914600cb..0b5a36a77 100644 --- a/app/commands/storage.html +++ b/app/commands/storage.html @@ -74,43 +74,48 @@

Storage

cy.clearLocalStorage()

To clear all data in localStorage for the current origin, use the cy.clearLocalStorage() command.

-
cy.get('.ls-btn').click().should(() => {
+          
cy.get('.ls-btn').click()
+cy.get('.ls-btn').should(() => {
   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((ls) => {
-  expect(ls.getItem('prop1')).to.be.null
-  expect(ls.getItem('prop2')).to.be.null
-  expect(ls.getItem('prop3')).to.be.null
+cy.clearLocalStorage()
+cy.getAllLocalStorage().should(() => {
+  expect(localStorage.getItem('prop1')).to.be.null
+  expect(localStorage.getItem('prop2')).to.be.null
+  expect(localStorage.getItem('prop3')).to.be.null
 })
 
-// Clear key matching string in localStorage
-cy.get('.ls-btn').click().should(() => {
+cy.get('.ls-btn').click()
+cy.get('.ls-btn').should(() => {
   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((ls) => {
-  expect(ls.getItem('prop1')).to.be.null
-  expect(ls.getItem('prop2')).to.eq('blue')
-  expect(ls.getItem('prop3')).to.eq('magenta')
+// Clear key matching string in localStorage
+cy.clearLocalStorage('prop1')
+cy.getAllLocalStorage().should(() => {
+  expect(localStorage.getItem('prop1')).to.be.null
+  expect(localStorage.getItem('prop2')).to.eq('blue')
+  expect(localStorage.getItem('prop3')).to.eq('magenta')
 })
 
-// Clear keys matching regex in localStorage
-cy.get('.ls-btn').click().should(() => {
+cy.get('.ls-btn').click()
+cy.get('.ls-btn').should(() => {
   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((ls) => {
-  expect(ls.getItem('prop1')).to.be.null
-  expect(ls.getItem('prop2')).to.be.null
-  expect(ls.getItem('prop3')).to.eq('magenta')
+// Clear keys matching regex in localStorage
+cy.clearLocalStorage(/prop1|2/)
+cy.getAllLocalStorage().should(() => {
+  expect(localStorage.getItem('prop1')).to.be.null
+  expect(localStorage.getItem('prop2')).to.be.null
+  expect(localStorage.getItem('prop3')).to.eq('magenta')
 })
@@ -208,7 +214,8 @@

cy.clearAllSessionSto
cy.get('.ls-btn').click()
 
 // clearAllSessionStorage() yields null
-cy.clearAllSessionStorage().should(() => {
+cy.clearAllSessionStorage()
+cy.getAllSessionStorage().should(() => {
   expect(sessionStorage.getItem('prop4')).to.be.null
   expect(sessionStorage.getItem('prop5')).to.be.null
   expect(sessionStorage.getItem('prop6')).to.be.null
diff --git a/app/index.html b/app/index.html
index 5cd8fae2b..61cdb2dc8 100644
--- a/app/index.html
+++ b/app/index.html
@@ -176,7 +176,6 @@ 

Commands

  • Misc
      -
    • end
    • exec
    • focused
    • screenshot
    • diff --git a/app/utilities.html b/app/utilities.html index b3fc65236..56b74b128 100644 --- a/app/utilities.html +++ b/app/utilities.html @@ -88,10 +88,9 @@

      Cypress.$

      To call a jQuery method, use the Cypress.$ command.

      let $li = Cypress.$('.utility-jquery li:first')
       
      -cy.wrap($li)
      -  .should('not.have.class', 'active')
      -  .click()
      -  .should('have.class', 'active')
      +cy.wrap($li).should('not.have.class', 'active') +cy.wrap($li).click() +cy.wrap($li).should('have.class', 'active')
  • @@ -115,21 +114,23 @@

    Cypress.$

    Cypress.Blob

    To work with blobs, convert strings, and other utility functions, use the Cypress.Blob library.

    -
    cy.get('.utility-blob').then(($div) =>
    -// https://github.com/nolanlawson/blob-util#imgSrcToDataURL
    -// get the dataUrl string for the javascript-logo
    -  Cypress.Blob.imgSrcToDataURL('/assets/img/javascript-logo.png', undefined, 'anonymous')
    +          
    cy.get('.utility-blob').then(($div) => {
    +  // https://github.com/nolanlawson/blob-util#imgSrcToDataURL
    +  // get the dataUrl string for the javascript-logo
    +  return Cypress.Blob.imgSrcToDataURL('/assets/img/javascript-logo.png', undefined, 'anonymous')
       .then((dataUrl) => {
         // create an  element and set its src to the dataUrl
         let img = Cypress.$('', { 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)
    -  }))
    + cy.get('.utility-blob img').should('have.attr', 'src', dataUrl) + }) +})
    diff --git a/cypress/e2e/2-advanced-examples/cookies.cy.js b/cypress/e2e/2-advanced-examples/cookies.cy.js index 03672f214..bb1e3f1b5 100644 --- a/cypress/e2e/2-advanced-examples/cookies.cy.js +++ b/cypress/e2e/2-advanced-examples/cookies.cy.js @@ -83,7 +83,6 @@ context('Cookies', () => { // cy.clearCookies() yields null cy.clearCookie('token') - cy.getCookie('token').should('be.null') cy.getCookie('token').should('be.null') }) diff --git a/cypress/e2e/2-advanced-examples/misc.cy.js b/cypress/e2e/2-advanced-examples/misc.cy.js index 0e15cb611..bae14fa9e 100644 --- a/cypress/e2e/2-advanced-examples/misc.cy.js +++ b/cypress/e2e/2-advanced-examples/misc.cy.js @@ -5,21 +5,6 @@ context('Misc', () => { cy.visit('http://localhost:8080/commands/misc') }) - it('.end() - end the command chain', () => { - // https://on.cypress.io/end - - // cy.end is useful when you want to end a chain of commands - // and force Cypress to re-query from the root element - cy.get('.misc-table').within(() => { - // 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', () => { // execute a system command. // so you can take actions necessary for