@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?

Selenium vs Cypress: Let the Code Speak

By Angie Jones

Selenium vs Cypress: Let the Code Speak

It's a battle of the code! Angie Jones represents Selenium WebDriver while Colby Fayock represents Cypress. Round for round, Angie and Colby take coding tasks and implement them in Selenium as well as Cypress, then analyze how each of the frameworks perform to solve real world testing challenges.

  • 4,162
Loading comments...

More from Angie Jones