Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comparing Playwright to SeleniumBase #3166

Open
chiangbar opened this issue Sep 26, 2024 · 3 comments
Open

Comparing Playwright to SeleniumBase #3166

chiangbar opened this issue Sep 26, 2024 · 3 comments
Assignees
Labels
documentation question Someone is looking for answers

Comments

@chiangbar
Copy link

Dear seleniumbase author, I am currently building a web testing platform. Can you compare the playwright library from a functional and performance perspective? This will also allow more engineers to recognize the great work of seleniumbase.🤣

@mdmintz mdmintz changed the title A good suggestion Comparing Playwright to SeleniumBase Sep 27, 2024
@mdmintz mdmintz added question Someone is looking for answers documentation labels Sep 27, 2024
@mdmintz mdmintz self-assigned this Sep 27, 2024
@mdmintz
Copy link
Member

mdmintz commented Sep 27, 2024

Both Playwright and SeleniumBase support different formats.

Playwright:

  • Python
  • pytest
  • .NET
  • Java
  • NodeJS.

SeleniumBase:

  • Python -> SB() and Driver()
  • pytest -> BaseCase class and sb fixture
  • BDD (Gherkin)

Since SeleniumBase doesn't have .NET, Java, or NodeJS formats, then Playwright is the only available choice if you need one of those. However, if you're a Python user, then we can make some meaningful comparisons.

Let's compare pytest formats for both:

Here's a Playwright example from https://playwright.dev/python/docs/writing-tests:

import re
from playwright.sync_api import Page, expect

def test_has_title(page: Page):
    page.goto("https://playwright.dev/")
    expect(page).to_have_title(re.compile("Playwright"))

def test_get_started_link(page: Page):
    page.goto("https://playwright.dev/")
    page.get_by_role("link", name="Get started").click()
    expect(page.get_by_role("heading", name="Installation")).to_be_visible()

Here's the SeleniumBase BaseCase version of that same example:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class MyTests(BaseCase):
    def test_has_title(self):
        self.open("https://playwright.dev/")
        self.assert_title_contains("Playwright")

    def test_get_started_link(self):
        self.open("https://playwright.dev/")
        self.click_link("Get started")
        self.assert_text("Installation", "h1")

And here's the SeleniumBase pytest fixture version: (No imports are needed)

def test_has_title(sb):
    sb.open("https://playwright.dev/")
    sb.assert_title_contains("Playwright")

def test_get_started_link(sb):
    sb.open("https://playwright.dev/")
    sb.click_link("Get started")
    sb.assert_text("Installation", "h1")

So for script simplicity, SeleniumBase is more simplified.

Let's compare Playwright code-gen to the SeleniumBase Recorder:

Playwright generated code:

from playwright.sync_api import Page, expect

def test_example(page: Page) -> None:
    page.got("https://demo.playwright.dev/todomvc/#/")
    page.get_by_placeholder("What needs to be done?").click()
    page.get_by_placeholder("What needs to be done?").fill("water the plants")
    page.get_by_placeholder("What needs to be done?").press("Enter")
    page.get_by_placeholder("What needs to be done?").fill("feed the dog")
    page.get_by_placeholder("What needs to be done?").press("Enter")
    page.locator("li").filter(has_text="water the plants").get_by_label("Toggle Todo").check()
    page.get_by_role("link", name="Completed").click()
    expect(page.get_by_test_id("todo-title")).to_contain_text("water the plants")
    page.get_by_role("link", name="Active").click()
    expect(page.get_by_test_id("todo-title")).to_contain_text("feed the dog")

Here's the same thing autogenerated with the SeleniumBase Recorder:

from seleniumbase import BaseCase
BaseCase.main(__name__, __file__)

class RecorderTest(BaseCase):
    def test_recording(self):
        self.open("https://demo.playwright.dev/todomvc/#/")
        self.type("input.new-todo", "water the plants\n")
        self.type("input.new-todo", "feed the dog\n")
        self.check_if_unchecked('input[aria-label="Toggle Todo"]')
        self.click('a[href="#/completed"]')
        self.assert_exact_text("water the plants", 'label[data-testid="todo-title"]')
        self.click('a[href="#/active"]')
        self.assert_exact_text("feed the dog", 'label[data-testid="todo-title"]')

(When using the Recorder, use SHIFT+7 to switch into Assert Text Mode, then ESC once to go back.)

As seen by the autogenerated code, the SeleniumBase version was more simplified.

Let's talk about methods: SeleniumBase has more Python methods than Playwright.

SeleniumBase also has a lot more tools, such as UC Mode, which lets you bypass CAPTCHAs.
(Playwright does not have that stealth ability.)

Here are some other tools that are unique to SeleniumBase:


Performance-wise, both frameworks are very similar. SeleniumBase also has several command-line options for speeding up tests, such as Reuse-Session Mode (--rs), which chains your tests together to reuse the same browser window. You can also change the pageLoadStrategy, Skip JS waits, and use headless mode for a speed boost.

@WaterLoran

This comment was marked as off-topic.

@WaterLoran

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation question Someone is looking for answers
Projects
None yet
Development

No branches or pull requests

3 participants