@techgirl1908
❝Existing Selenium projects will continue for a long time, but after learning Playwright, I will never start a new E2E test project in Selenium.❞ ~ Andrejs
@AutomationPanda
@techgirl1908
❝I have used both for some time now and can’t wait to see what points both speakers put.❞ ~ Rahul
@AutomationPanda
@techgirl1908
❝I have used both selenium and playwright(js binding). For me playwright is the clear winner. Let the code speak❞ ~ Dushyant
@AutomationPanda
@techgirl1908
@AutomationPanda
❝About time Selenium got a worthy competitor. I've been a WebDriver fan for good 7+ years and can’t wait to see how long will Playwright survive against it 😉❞ ~ Akash
@techgirl1908
@AutomationPanda
❝Sorry Angie. On this one I’m team Andy, my bet is on Playwright❞ ~ Ixchel
@techgirl1908
@AutomationPanda
❝Playwright is absolutely changing the game! Automatic waits, built in device and multiple browser support, available in Python, JS, and more! ❞ ~ Sean
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
🥊 10 Rounds
💻 Show implementations in Selenium and Playwright
🗳 You vote
💬 Discuss after each round
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@Test
public void testLogin()
{
page.navigate("https://demo.applitools.com/");
page.fill("id=username", "andy");
page.fill("id=password", "panda<3");
page.click("id=log-in");
assertThat(page.locator(".element-header >> nth=0"))
.hasText("Financial Overview");
}
@techgirl1908
@AutomationPanda
@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());
}
@Test
public void testLogin()
{
page.navigate("https://demo.applitools.com/");
page.fill("id=username", "andy");
page.fill("id=password", "panda<3");
page.click("id=log-in");
assertThat(page.locator(".element-header >> nth=0"))
.hasText("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());
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@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
@AutomationPanda
@Test
public void testDropdown()
{
page.navigate("https://kitchen.applitools.com/ingredients/select");
page.selectOption("id=spices-select-single", "ginger");
assertThat(page.locator("id=spices-select-single"))
.hasValue("ginger");
}
@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"));
}
@Test
public void testDropdown()
{
page.navigate("https://kitchen.applitools.com/ingredients/select");
page.selectOption("id=spices-select-single", "ginger");
assertThat(page.locator("id=spices-select-single"))
.hasValue("ginger");
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@Test
public void testFileUpload()
{
page.navigate("https://kitchen.applitools.com/ingredients/file-picker");
page.setInputFiles("id=photo-upload", Paths.get("pic.jpg"));
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@Test
public void testFileUpload()
{
driver.get("https://kitchen.applitools.com/ingredients/file-picker");
driver.findElement(By.id("photo-upload")).sendKeys("/Users/angie/tmp/pic.jpg");
}
@Test
public void testFileUpload()
{
driver.get("https://kitchen.applitools.com/ingredients/file-picker");
driver.findElement(By.id("photo-upload")).sendKeys("/Users/angie/tmp/pic.jpg");
}
@Test
public void testFileUpload()
{
page.navigate("https://kitchen.applitools.com/ingredients/file-picker");
page.setInputFiles("id=photo-upload", Paths.get("pic.jpg"));
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@Test
public void testIframe()
{
driver.get("https://kitchen.applitools.com/ingredients/iframe");
assertTrue(
driver.switchTo().frame("the-kitchen-table")
.findElement(By.id("fruits-vegetables"))
.isDisplayed());
}
@techgirl1908
@Test
public void testIframe()
{
page.navigate("https://kitchen.applitools.com/ingredients/iframe");
assertThat(page
.frameLocator("id=the-kitchen-table")
.locator("id=fruits-vegetables")
).isVisible();
}
@AutomationPanda
@Test
public void testIframe()
{
driver.get("https://kitchen.applitools.com/ingredients/iframe");
assertTrue(
driver.switchTo().frame("the-kitchen-table")
.findElement(By.id("fruits-vegetables"))
.isDisplayed());
}
@Test
public void testIframe()
{
page.navigate("https://kitchen.applitools.com/ingredients/iframe");
assertThat(
page.frameLocator("id=the-kitchen-table")
.locator("id=fruits-vegetables")
).isVisible();
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@Test
public void testWaitForFilter()
{
page.navigate("https://automationbookstore.dev/");
page.fill("id=searchBar", "testing");
page.locator("li.ui-screen-hidden >> nth=0").waitFor(
new Locator.WaitForOptions()
.setState(WaitForSelectorState.HIDDEN)
.setTimeout(5000));
assertThat(page.locator("li:not(.ui-screen-hidden)"))
.hasCount(1, new LocatorAssertions.HasCountOptions().setTimeout(5000));
}
@AutomationPanda
@techgirl1908
@Test
public void testWaitForFilter()
{
page.navigate("https://automationbookstore.dev/");
page.fill("id=searchBar", "testing");
// page.locator("li.ui-screen-hidden >> nth=0").waitFor(
// new Locator.WaitForOptions()
// .setState(WaitForSelectorState.HIDDEN)
// .setTimeout(5000));
assertThat(page.locator("li:not(.ui-screen-hidden)"))
.hasCount(1, new LocatorAssertions.HasCountOptions().setTimeout(5000));
}
@AutomationPanda
Explicitly waiting for hidden elements to attach to the DOM is not required.
Waiting for the non-hidden element count to reach 1 inherently covers it.
@techgirl1908
@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());
}
@AutomationPanda
@techgirl1908
@Test
public void testWaitForFilter()
{
...
new WebDriverWait(driver, Duration.ofSeconds(5))
.until(presenceOfElementLocated(
By.cssSelector("li.ui-screen-hidden"))
);
...
}
@Test
public void testWaitForFilter()
{
...
page.locator("li.ui-screen-hidden >> nth=0").waitFor(
new Locator.WaitForOptions()
.setState(WaitForSelectorState.HIDDEN)
.setTimeout(5000));
...
}
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@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
@AutomationPanda
@BeforeAll
public static void openAlertsPage(){
page.navigate("https://kitchen.applitools.com/ingredients/alert");
}
@Test
public void testAcceptAlert(){
page.onDialog(Dialog::accept);
page.click("id=alert-button");
}
@Test
public void testDismissAlert(){
page.onDialog(Dialog::dismiss);
page.click("id=confirm-button");
}
@Test
public void testAnswerPrompt(){
page.onDialog(dialog -> dialog.accept("nachos"));
page.click("id=prompt-button");
}
@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();
}
@BeforeAll
public static void openAlertsPage(){
page.navigate("https://kitchen.applitools.com/ingredients/alert");
}
@Test
public void testAcceptAlert(){
page.onDialog(Dialog::accept);
page.click("id=alert-button");
}
@Test
public void testDismissAlert(){
page.onDialog(Dialog::dismiss);
page.click("id=confirm-button");
}
@Test
public void testAnswerPrompt(){
page.onDialog(dialog -> dialog.accept("nachos"));
page.click("id=prompt-button");
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@Test
public void testNewTab()
{
page.navigate("https://kitchen.applitools.com/ingredients/links");
Page newTab = context.waitForPage(
() -> page.click("id=button-the-kitchen-table"));
assertThat(newTab.locator("id=fruits-vegetables")).isVisible();
}
@AutomationPanda
@techgirl1908
@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());
}
@AutomationPanda
@techgirl1908
@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());
}
@AutomationPanda
@Test
public void testNewTab()
{
page.navigate("https://kitchen.applitools.com/ingredients/links");
Page newTab = context.waitForPage(
() -> page.click("id=button-the-kitchen-table"));
assertThat(newTab.locator("id=fruits-vegetables")).isVisible();
}
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
https://kitchen.applitools.com/api/recipes
@techgirl1908
😫
@AutomationPanda
@techgirl1908
@AutomationPanda
Currently, Playwright provides API testing
only for JavaScript and Python.
API testing support will come to Java in 1.18.
It will come to .NET thereafter.
😲
@techgirl1908
def test_kitchen_api_recipes(context):
response = context.request.get(
'https://kitchen.applitools.com/api/recipes')
body = response.json()
assert response.ok
assert body['time'] > 0
assert len(body['data']) > 0
# Include other assertions about body data as appropriate
@AutomationPanda
@techgirl1908
def test_kitchen_api_recipes(context):
response = context.request.get(
'https://kitchen.applitools.com/api/recipes')
body = response.json()
assert response.ok
assert body['time'] > 0
assert len(body['data']) > 0
# Include other assertions about body data as appropriate
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@Test
public void testScreenshot()
{
page.navigate("https://kitchen.applitools.com/ingredients/table");
page.click("id=column-button-name");
page.screenshot(
new Page.ScreenshotOptions()
.setPath(Paths.get("fullPage.png"))
.setFullPage(true));
}
@AutomationPanda
@techgirl1908
@Test
public void testScreenshot()
{
driver.get("https://kitchen.applitools.com/ingredients/table");
driver.findElement(By.id("column-button-name")).click();
var screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try{
Files.move(screenshot, new File("resources/screenshots/test.png"));
}catch(IOException e){
e.printStackTrace();
}
}
@AutomationPanda
@techgirl1908
@Test
public void testScreenshot(){
driver.get("https://kitchen.applitools.com/ingredients/table");
driver.findElement(By.id("column-button-name")).click();
var screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try{
Files.move(screenshot, new File("resources/screenshots/test.png"));
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void testScreenshot()
{
page.navigate("https://kitchen.applitools.com/ingredients/table");
page.click("id=column-button-name");
page.screenshot(
new Page.ScreenshotOptions()
.setPath(Paths.get("fullPage.png"))
.setFullPage(true));
}
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
@techgirl1908
@AutomationPanda
Selenium WebDriver does not support
video recording out of the box!
😫
@techgirl1908
@BeforeEach
public void startPage() {
context = browser.newContext(
new Browser.NewContextOptions()
.setRecordVideoDir(Paths.get("videos/")));
page = context.newPage();
}
@AfterEach
public void closePage() {
context.close();
}
@Test
public void testLogin() {
// This is the same code from Round 1
...
}
@AutomationPanda
@techgirl1908
@BeforeEach
public void startPage() {
context = browser.newContext(
new Browser.NewContextOptions()
.setRecordVideoDir(Paths.get("videos/")));
page = context.newPage();
}
@AfterEach
public void closePage() {
context.close();
}
...
@AutomationPanda
Selenium WebDriver does not support
video recording out of the box!
@techgirl1908
@AutomationPanda