@techgirl1908

@colbyfayock

❝I'm giving it to Cypress ahead of time, smoother than Selenium in my humble opinion❞ ~ Umi

VS

@techgirl1908

@colbyfayock

❝I’ll strongly pick Selenium. Robust code base. Very easy to understand. Fast adoption too!❞ ~ Shittu

VS

@techgirl1908

@colbyfayock

❝I am putting my money on Cypress although I know a framework is as good as its user. I am taking a gamble!❞ ~ MrTechHandle

VS

@techgirl1908

@colbyfayock

❝Before Selenium 4, my bet would have been on Cypress but now....Selenium might just nudge Cypress!❞ ~ Kartik

VS

@techgirl1908

@colbyfayock

📰 Selenium vs. Cypress: Is WebDriver on Its Way Out?

VS

Yet another

Selenium vs Cypress comparison?! 🙄

@techgirl1908

@colbyfayock

👩🏽‍💻Selenium WebDriver (Java)

 

🧑🏻‍💻Cypress

(JavaScript)

@techgirl1908

@colbyfayock

The Battle

@techgirl1908

@colbyfayock

🥊 10 Rounds
 

💻 Show implementations in both Cypress and Selenium
 

🗳 You vote
 

💬 Discuss after each round

Round 1:

Element Interaction

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 1: Cypress

describe("Login", () => {

  it('should log into the application', () => {
    cy.visit('https://demo.applitools.com/');
    cy.get('#username').type('colbyfayock');
    cy.get('#password').type('Password1234');
    cy.get('#log-in').click();
    cy.get('.element-header').contains('Financial Overview');
  });

});

@techgirl1908

@colbyfayock

Round 1: Selenium

@Test
public void testLogin()
{
    driver.get("https://demo.applitools.com/");
    driver.findElement(By.id("username")).sendKeys("angie");
    driver.findElement(By.id("password")).sendKeys("12345");
    driver.findElement(By.id("log-in")).click();
    assertEquals(
            "Financial Overview",
            driver.findElement(By.className("element-header")).getText());
}

Round 1: Selenium vs Cypress

describe("Login", () => {

  it('should log into the application', () => {
    cy.visit('https://demo.applitools.com/');
    cy.get('#username').type('colbyfayock');
    cy.get('#password').type('Password1234');
    cy.get('#log-in').click();
    cy.get('.element-header').contains('Financial Overview');
  });

});
@Test
public void testLogin()
{
    driver.get("https://demo.applitools.com/");
    driver.findElement(By.id("username")).sendKeys("angie");
    driver.findElement(By.id("password")).sendKeys("12345");
    driver.findElement(By.id("log-in")).click();
    assertEquals(
            "Financial Overview",
            driver.findElement(By.className("element-header")).getText());
}

💬 Discussion

@techgirl1908

@colbyfayock

Round 2: Dropdowns

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 2: Selenium

@Test
public void testDropdown() {
    driver.get("https://kitchen.applitools.com/ingredients/select");
    
    Select dropdown = 
        new Select(driver.findElement(By.id("spices-select-single")));
        
    dropdown.selectByValue("ginger");
    
    assertEquals("ginger", 
        dropdown.getAllSelectedOptions().get(0).getAttribute("value"));
}

@techgirl1908

@colbyfayock

Round 2: Cypress

describe("Select", () => {

  it('should select an option from the dropdown', () => {
    cy.visit('/ingredients/select');
    cy.get('#spices-select-single')
      .select('ginger')
      .should('have.value', 'ginger')
  });

});

Round 2: Selenium vs Cypress

@Test
public void testDropdown() {
    driver.get("https://kitchen.applitools.com/ingredients/select");
    
    Select dropdown = 
        new Select(driver.findElement(By.id("spices-select-single")));
        
    dropdown.selectByValue("ginger");
    
    assertEquals("ginger", 
        dropdown.getAllSelectedOptions().get(0).getAttribute("value"));
}
describe("Select", () => {

  it('should select an option from the dropdown', () => {
    cy.visit('/ingredients/select');
    cy.get('#spices-select-single')
      .select('ginger')
      .should('have.value', 'ginger')
  });

});

💬 Discussion

@techgirl1908

@colbyfayock

Round 3:

Uploading Files

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 3: Cypress

describe("File Picker", () => {

  it('should upload a photo to the file picker', () => {
    cy.visit('/ingredients/file-picker');

    cy.fixture('images/french-toast.jpg').as('photo');

    cy.get('#photo-upload').then(function (el) {
      const blob = Cypress.Blob.base64StringToBlob(this.photo, 'image/jpeg');

      const file = new File([blob], 'images/french-toast.jpg', {
        type: 'image/jpeg'
      });
      
      const data = new DataTransfer();
      data.items.add(file);
      el[0].files = data.files;
      
      const changeEvent = new Event('change', {
        bubbles: true
      });
      
      el[0].dispatchEvent(changeEvent);
    });

    cy.get('#photo-upload').next().next().should('be.visible');
  });

});

@techgirl1908

@colbyfayock

Round 3: Selenium

@Test
public void testFileUpload() {
    driver.get("https://kitchen.applitools.com/ingredients/file-picker");
    driver.findElement(By.id("photo-upload")).sendKeys("pic.jpg");
}

Round 3: Selenium vs Cypress

@Test
public void testFileUpload() {
    driver.get("https://kitchen.applitools.com/ingredients/file-picker");
    driver.findElement(By.id("photo-upload")).sendKeys("pic.jpg");
}
describe("File Picker", () => {

  it('should upload a photo to the file picker', () => {
    cy.visit('/ingredients/file-picker');

    cy.fixture('images/french-toast.jpg').as('photo');

    cy.get('#photo-upload').then(function (el) {
      const blob = Cypress.Blob.base64StringToBlob(this.photo, 'image/jpeg');

      const file = new File([blob], 'images/french-toast.jpg', {
        type: 'image/jpeg'
      });
      
      const data = new DataTransfer();
      data.items.add(file);
      el[0].files = data.files;
      
      const changeEvent = new Event('change', {
        bubbles: true
      });
      
      el[0].dispatchEvent(changeEvent);
    });

    cy.get('#photo-upload').next().next().should('be.visible');
  });

});

@techgirl1908

@colbyfayock

Round 3: Cypress Plugin

describe("File Picker", () => {

  it('should upload a photo to the file picker', () => {
    
    cy.get('#photo-upload').attachFile('images/french-toast.jpg');
    cy.get('#photo-upload').next().next().should('be.visible');
    
  });

});

💬 Discussion

@techgirl1908

@colbyfayock

Round 4: Frames

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 4: Selenium (same domain)

@Test
public void testIframe_SameDomain(){
    driver.get("https://kitchen.applitools.com/ingredients/iframe");
    assertTrue(
            driver.switchTo().frame("the-kitchen-table")
            .findElement(By.id("fruits-vegetables"))
            .isDisplayed()
    );
}

@techgirl1908

@colbyfayock

Round 4: Cypress (same domain)

describe("iFrame", () => {

  it('should find a table in the iframe', () => {
    cy.visit('/ingredients/iframe');
    cy.get('#the-kitchen-table')
      .its('0.contentDocument')
      .its('body')
      .then(cy.wrap)
      .find('#fruits-vegetables')
      .should('be.visible');
  });

});

@techgirl1908

@colbyfayock

Round 4: Selenium (cross-domain)

@Test
public void testIframe_CrossDomain(){
    driver.get("https://kitchen.applitools.com/ingredients/iframe");
    assertTrue(
            driver.switchTo().frame("youtube-table-cypress")
            .findElement(By.id("player"))
            .isDisplayed()
    );
}

@techgirl1908

@colbyfayock

Round 4: Cypress (cross-domain)

😫

Round 4: Selenium vs Cypress

@Test
public void testIframe_SameDomain(){
    driver.get("https://kitchen.applitools.com/ingredients/iframe");
    assertTrue(
            driver.switchTo().frame("the-kitchen-table")
            .findElement(By.id("fruits-vegetables"))
            .isDisplayed()
    );
}
describe("iFrame", () => {

  it('should find a table in the iframe', () => {
    cy.visit('/ingredients/iframe');
    cy.get('#the-kitchen-table')
      .its('0.contentDocument')
      .its('body')
      .then(cy.wrap)
      .find('#fruits-vegetables')
      .should('be.visible');
  });

});

cross-domain iframes

cross-domain iframes

💬 Discussion

@techgirl1908

@colbyfayock

Round 5: Waiting

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 5: Cypress

describe('Search for books', () => {

    it('should return one book', () => {
        cy.visit('https://automationbookstore.dev/');
        cy.get('#searchBar').type('testing');
      
        expect(
          cy.get('li.ui-screen-hidden').
          its('length')
        ).to.not.equal(0);
      
        cy.get('li:not(.ui-screen-hidden)')
          .should('have.length', 1);
    });
});

@techgirl1908

@colbyfayock

Round 5: Selenium

@Test
public void testWaitForFilter(){
    driver.get("https://automationbookstore.dev/");
    driver.findElement(By.id("searchBar")).sendKeys("testing");
    
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(presenceOfElementLocated(
            By.cssSelector("li.ui-screen-hidden"))
        );
   
    assertEquals(1, 
        driver.findElements(By.cssSelector("li:not(.ui-screen-hidden)"))
            .size());
}

@techgirl1908

@colbyfayock

Round 5: Selenium vs Cypress

@Test
public void testWaitForFilter(){
    ...
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(presenceOfElementLocated(
            By.cssSelector("li.ui-screen-hidden"))
        );
   
    ...
}
describe('Search for books', () => {

    it('should return one book', () => {
        ...
        expect(
          cy.get('li.ui-screen-hidden').
          its('length')
        ).to.not.equal(0);
        ...
    })
})

💬 Discussion

@techgirl1908

@colbyfayock

Round 6: Alerts

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 6: Selenium

@BeforeAll
public static void openAlertsPage(){
    driver.get("https://kitchen.applitools.com/ingredients/alert");
}

@Test
public void testAcceptAlert(){
    driver.findElement(By.id("alert-button")).click();
    driver.switchTo().alert().accept();
}

@Test
public void testDismissAlert(){
    driver.findElement(By.id("confirm-button")).click();
    driver.switchTo().alert().dismiss();
}

@Test
public void testAnswerPrompt(){
    driver.findElement(By.id("prompt-button")).click();
    Alert alert = driver.switchTo().alert();
    alert.sendKeys("nachos");
    alert.accept();
}

@techgirl1908

@colbyfayock

Round 6: Cypress

describe("Alert", () => {

  beforeEach(() => {
    cy.visit('/ingredients/alert');
  });
  
  it('should trigger an alert with a message', () => {
    cy.get('#alert-button').click();
    
    cy.on('window:alert', (text) => {
      expect(text).to.contains('Airfryers can make anything!');
    });
  });
  
  
  it('should trigger a confirmation with a message and cancel', () => {
    cy.get('#confirm-button').click();

    cy.on('window:confirm', (text) => {
      expect(text).to.contains('Proceed with adding garlic?');
      return false;
    });
  });
  

  it('should trigger a prompt with a message', () => {
    cy.window().then(win => {
      cy.stub(win, 'prompt').returns('Pizza!');
      cy.get('#prompt-button').click();
    });
  });

});

Round 6: Selenium vs Cypress

@BeforeAll
public static void openAlertsPage(){
    driver.get("https://kitchen.applitools.com/ingredients/alert");
}

@Test
public void testAcceptAlert(){
    driver.findElement(By.id("alert-button")).click();
    driver.switchTo().alert().accept();
}

@Test
public void testDismissAlert(){
    driver.findElement(By.id("confirm-button")).click();
    driver.switchTo().alert().dismiss();
}

@Test
public void testAnswerPrompt(){
    driver.findElement(By.id("prompt-button")).click();
    Alert alert = driver.switchTo().alert();
    alert.sendKeys("nachos");
    alert.accept();
}
describe("Alert", () => {

  beforeEach(() => {
    cy.visit('/ingredients/alert');
  });
  
  it('should trigger an alert with a message', () => {
    cy.get('#alert-button').click();
    
    cy.on('window:alert', (text) => {
      expect(text).to.contains('Airfryers can make anything!');
    });
  });
  
  
  it('should trigger a confirmation with a message and cancel', () => {
    cy.get('#confirm-button').click();

    cy.on('window:confirm', (text) => {
      expect(text).to.contains('Proceed with adding garlic?');
      return false;
    });
  });

  
  it('should trigger a prompt with a message', () => {
    cy.window().then(win => {
      cy.stub(win, 'prompt').returns('Pizza!');
      cy.get('#prompt-button').click();
    });
  });

});

💬 Discussion

@techgirl1908

@colbyfayock

Round 7: Navigation

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 7: Cypress

😫

@techgirl1908

@colbyfayock

Round 7: Selenium

@Test
public void testNewTab(){
    driver.get("https://kitchen.applitools.com/ingredients/links");
    driver.findElement(By.id("button-the-kitchen-table")).click();
    driver.getWindowHandles().forEach(tab->driver.switchTo().window(tab));
    assertTrue(driver.findElement(By.id("fruits-vegetables")).isDisplayed());
}

@techgirl1908

@colbyfayock

Round 7: Selenium vs Cypress

@Test
public void testNewTab(){
    driver.get("https://kitchen.applitools.com/ingredients/links");
    driver.findElement(By.id("button-the-kitchen-table")).click();
    driver.getWindowHandles().forEach(tab->driver.switchTo().window(tab));
    assertTrue(driver.findElement(By.id("fruits-vegetables")).isDisplayed());
}

💬 Discussion

@techgirl1908

@colbyfayock

Round 8: API Requests

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

https://api.tenor.com/v1/search?q=thank%20you

@techgirl1908

@colbyfayock

Round 8: Selenium

😫

@techgirl1908

@colbyfayock

Round 8: Cypress

describe("API", () => {

  it('should trigger an alert with a message', () => {
    cy.visit('https://tenor.com/search/thank-you-gifs');
    cy.request(`https://api.tenor.com/v1/search?q=thank%20you&limit=1`)
      .then((response) => {
         const imgUrl = response.body.results[0].media[0].tinygif.url;
         cy.get('.GifList .Gif img').should('have.attr', 'src')
           .should('include', imgUrl);
    });
  });

});

@techgirl1908

@colbyfayock

Round 8: Selenium vs Cypress

describe("API", () => {

  it('should trigger an alert with a message', () => {
    cy.visit('https://tenor.com/search/thank-you-gifs');
    cy.request(`https://api.tenor.com/v1/search?q=thank%20you&limit=1`)
      .then((response) => {
         const imgUrl = response.body.results[0].media[0].tinygif.url;
         cy.get('.GifList .Gif img').should('have.attr', 'src')
           .should('include', imgUrl);
    });
  });

});

💬 Discussion

@techgirl1908

@colbyfayock

Round 9: Screenshots

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 9: Cypress

describe("Screenshot", () => {

  it('should take a screenshot', () => {
    cy.visit('/ingredients/table');
    cy.get('#column-button-name').click();
    cy.screenshot();
  });

});

@techgirl1908

@colbyfayock

Round 9: Selenium

@Test
public void testScreenshot(){
    driver.get("https://kitchen.applitools.com/ingredients/table");
    driver.findElement(By.id("column-button-name")).click();
    ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
}

@techgirl1908

@colbyfayock

Round 9: Selenium vs Cypress

@Test
public void testScreenshot(){
    driver.get("https://kitchen.applitools.com/ingredients/table");
    driver.findElement(By.id("column-button-name")).click();
    ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
}
describe("Screenshot", () => {

  it('should take a screenshot', () => {
    cy.visit('/ingredients/table');
    cy.get('#column-button-name').click();
    cy.screenshot();
  });

});

💬 Discussion

@techgirl1908

@colbyfayock

Round 10: Integrations

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Round 10: Selenium

@Test
public void testSortByName_withVisualTesting(){
    driver.get("https://kitchen.applitools.com/ingredients/table");
    driver.findElement(By.id("column-button-name")).click();

    Eyes eyes = new Eyes();
    eyes.open(driver, "The Kitchen", "sort by name");
    eyes.checkWindow();
    eyes.close();
}

@techgirl1908

@colbyfayock

Round 10: Cypress

  describe('Visual Testing', () => {

    it('should verify table is sorted ascending', () => {
      cy.visit('/ingredients/table');
      cy.get('#column-button-name').click();

      cy.eyesOpen({ appName: 'The Kitchen', testName: 'sort by name'});
      cy.eyesCheckWindow();
      cy.eyesClose();
    });

  });

@techgirl1908

@colbyfayock

Round 10: Selenium vs Cypress

@Test
public void testSortByName_withVisualTesting(){
    driver.get("https://kitchen.applitools.com/ingredients/table");
    driver.findElement(By.id("column-button-name")).click();

    Eyes eyes = new Eyes();
    eyes.open(driver, "The Kitchen", "sort by name");
    eyes.checkWindow();
    eyes.close();
}
  describe('Visual Testing', () => {
    
    it('should verify table is sorted ascending', () => {
      cy.visit('/ingredients/table');
      cy.get('#column-button-name').click();

      cy.eyesOpen({ appName: 'The Kitchen', testName: 'sort by name'});
      cy.eyesCheckWindow();
      cy.eyesClose();
    });
  });

💬 Discussion

@techgirl1908

@colbyfayock

@techgirl1908

@colbyfayock

Selenium or Cypress:

 

 

 

 

Who's the Winner?