Giter Site home page Giter Site logo

microsoft / playwright-pytest Goto Github PK

View Code? Open in Web Editor NEW
400.0 19.0 64.0 130 KB

Pytest plugin to write end-to-end browser tests with Playwright.

Home Page: https://playwright.dev/python/docs/test-runners

License: Apache License 2.0

Python 100.00%
pytest-plugin playwright testing-tools

playwright-pytest's Introduction

Pytest plugin for Playwright PyPI

Write end-to-end tests for your web apps with Playwright and pytest.

  • Support for all modern browsers including Chromium, WebKit and Firefox.
  • Support for headless and headed execution.
  • Built-in fixtures that provide browser primitives to test functions.

Documentation

See on playwright.dev for examples and more detailed information.

playwright-pytest's People

Contributors

aklajnert avatar arjunattam avatar cclauss avatar cgbassplayer avatar dependabot[bot] avatar fcollonval avatar jcushman avatar jensenbox avatar jerichokeyne avatar kumaraditya303 avatar m9810223 avatar microsoftopensource avatar mxschmitt avatar owenlamont avatar pavelfeldman avatar razerm avatar rwoll avatar skarzi avatar symonk avatar tonybaloney avatar ujetter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

playwright-pytest's Issues

[BUG] device emulation is not possible

Hi all!
How can I start tests, when I want to run it as it's browser on IPhone? Something like, but in the fixture:

 iphone_11 = p.devices['iPhone 11 Pro']
    browser = p.webkit.launch(headless=False)
    context = browser.newContext(
        **iphone_11,
        locale='en-US',
        geolocation={ 'longitude': 12.492507, 'latitude': 41.889938 },
        permissions=['geolocation']
    )

As I read in documentation, it's possible only to specify browser.

AttributeError: 'WebDriver' object has no attribute 'new_context' after update to 0.0.11 version

Hi!
I use following versions

playwright==1.8.0a1
pytest-playwright==0.0.11

When I try to run this simple test

import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
    return {
        **browser_context_args,
        "viewport": {
            "width": 1920,
            "height": 1080,
        }
    }


def test_3(page):
    page.goto("https://github.com/")

I see the following errors


test_3.py::test_3 ERROR                                                                                                      [100%]
test_3.py::test_3 ERROR                                                                                                      [100%]

============================================================== ERRORS ==============================================================
_____________________________________________________ ERROR at setup of test_3 _____________________________________________________

browser = <selenium.webdriver.chrome.webdriver.WebDriver (session="a04299d9467e720629597b732e376de3")>
browser_context_args = {'viewport': {'height': 1080, 'width': 1920}}

   @pytest.fixture
   def context(
       browser: Browser, browser_context_args: Dict
   ) -> Generator[BrowserContext, None, None]:
>       context = browser.new_context(**browser_context_args)
E       AttributeError: 'WebDriver' object has no attribute 'new_context'

../../.venv/lib/python3.9/site-packages/pytest_playwright/pytest_playwright.py:128: AttributeError
------------------------------------------------------ Captured stdout setup -------------------------------------------------------
['--start-maximized', 'window-size=2560,1440']
___________________________________________________ ERROR at teardown of test_3 ____________________________________________________

request = <SubRequest 'browser' for <Function test_3>>

   @pytest.fixture()
   def browser(request):
       browser = None
       options = get_browser_options(request)
       # check, if we try to pass arguments
       if hasattr(request, 'param'):
           # parse param
           params = request.param.split(", ")
           print(params)
           if params[0] == "experimenatal_option":
               print(params[1], params[2], params[3])
               options.add_experimental_option(params[1], {params[2]: params[3]})
       # options.add_experimental_option("w3c", False)
       # add for allowing to see network logs
       caps = DesiredCapabilities.CHROME
       #as per latest docs
       caps['goog:loggingPrefs'] = {'performance': 'ALL'}
       browser = webdriver.Chrome(desired_capabilities=caps, options=options)
       browser.implicitly_wait(5)
       yield browser
       # Do teardown (this code will be executed after each test):
       #print(request.node.rep_call)
       # to do - if broken, pls make a screenshot
>       if request.node.rep_call.failed:
E       AttributeError: 'Function' object has no attribute 'rep_call'

../../config/init_browser.py:55: AttributeError
------------------------------------------------------ Captured stdout setup -------------------------------------------------------
['--start-maximized', 'window-size=2560,1440']
===================================================== short test summary info ======================================================
ERROR test_3.py::test_3 - AttributeError: 'WebDriver' object has no attribute 'new_context'
ERROR test_3.py::test_3 - AttributeError: 'Function' object has no attribute 'rep_call'

Pytest fixture - how can I run the same instance of the page for each (py)test?

Hello guys!

First of all congratulations for the hard work involved in Playwright!

I know this is not really an "issue" but I'll try my luck here guys.

How can you setup a page instance in which all the tests are run in the same page? Using Playwright / Pytest.

For example:

1 - Open https://en.wikipedia.org/wiki/Main_Page

2 - Check that Search field is visible

3 - Check that the logo is displayed

... but all without reopening the browser for each test!

I have checked the documentation but still I can't find how to do it.

Note that I'm a beginner.

Thanks!

`page` fixture: You cannot call this from an async context - use a thread or sync_to_async.

I get this Exception, if I try to use the page fixture together with the live_server fixture of "pytest-django".


(lala-env) guettli@yoga15:~/projects/lala-env/src/lala$ pytest -k chili
============================================================================== test session starts ===============================================================================
platform linux -- Python 3.8.5, pytest-6.2.0, py-1.10.0, pluggy-0.13.1
django: settings: mysite.settings (from env)
rootdir: /home/guettli/projects/lala-env/src/lala, configfile: pytest.ini
plugins: django-4.1.0, playwright-0.0.12, base-url-1.4.2
collected 61 items / 60 deselected / 1 selected                                                                                                                                  

lala/playwright/create_testdata_add_address_order_chili_test.py E

===================================================================================== ERRORS =====================================================================================
______________________________________________________________________ ERROR at setup of test_it[chromium] _______________________________________________________________________

self = <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f987e645e80>

    @contextmanager
    def _nodb_cursor(self):
        """
        Return a cursor from an alternative connection to be used when there is
        no need to access the main database, specifically for test db
        creation/deletion. This also prevents the production database from
        being exposed to potential child threads while (or after) the test
        database is destroyed. Refs #10868, #17786, #16969.
        """
        conn = self.__class__({**self.settings_dict, 'NAME': None}, alias=NO_DB_ALIAS)
        try:
>           with conn.cursor() as cursor:

../../lib/python3.8/site-packages/django/db/backends/base/base.py:620: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (<django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f9877798160>,), kwargs = {}, event_loop = <_UnixSelectorEventLoop running=True closed=False debug=False>

    @functools.wraps(func)
    def inner(*args, **kwargs):
        if not os.environ.get('DJANGO_ALLOW_ASYNC_UNSAFE'):
            # Detect a running event loop in this thread.
            try:
                event_loop = asyncio.get_event_loop()
            except RuntimeError:
                pass
            else:
                if event_loop.is_running():
>                   raise SynchronousOnlyOperation(message)
E                   django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

../../lib/python3.8/site-packages/django/utils/asyncio.py:24: SynchronousOnlyOperation

During handling of the above exception, another exception occurred:

request = <SubRequest '_live_server_helper' for <Function test_it[chromium]>>

    @pytest.fixture(autouse=True, scope="function")
    def _live_server_helper(request):
        """Helper to make live_server work, internal to pytest-django.
    
        This helper will dynamically request the transactional_db fixture
        for a test which uses the live_server fixture.  This allows the
        server and test to access the database without having to mark
        this explicitly which is handy since it is usually required and
        matches the Django behaviour.
    
        The separate helper is required since live_server can not request
        transactional_db directly since it is session scoped instead of
        function-scoped.
    
        It will also override settings only for the duration of the test.
        """
        if "live_server" not in request.fixturenames:
            return
    
>       request.getfixturevalue("transactional_db")

../../lib/python3.8/site-packages/pytest_django/fixtures.py:440: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../lib/python3.8/site-packages/pytest_django/fixtures.py:105: in django_db_setup
    db_cfg = setup_databases(
../../lib/python3.8/site-packages/django/test/utils.py:170: in setup_databases
    connection.creation.create_test_db(
../../lib/python3.8/site-packages/django/db/backends/base/creation.py:55: in create_test_db
    self._create_test_db(verbosity, autoclobber, keepdb)
../../lib/python3.8/site-packages/django/db/backends/base/creation.py:186: in _create_test_db
    with self._nodb_cursor() as cursor:
/usr/lib/python3.8/contextlib.py:113: in __enter__
    return next(self.gen)
../../lib/python3.8/site-packages/django/db/backends/postgresql/base.py:301: in _nodb_cursor
    with super()._nodb_cursor() as cursor:
/usr/lib/python3.8/contextlib.py:113: in __enter__
    return next(self.gen)
../../lib/python3.8/site-packages/django/db/backends/base/base.py:623: in _nodb_cursor
    conn.close()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (<django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f9877798160>,), kwargs = {}, event_loop = <_UnixSelectorEventLoop running=True closed=False debug=False>

    @functools.wraps(func)
    def inner(*args, **kwargs):
        if not os.environ.get('DJANGO_ALLOW_ASYNC_UNSAFE'):
            # Detect a running event loop in this thread.
            try:
                event_loop = asyncio.get_event_loop()
            except RuntimeError:
                pass
            else:
                if event_loop.is_running():
>                   raise SynchronousOnlyOperation(message)
E                   django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

../../lib/python3.8/site-packages/django/utils/asyncio.py:24: SynchronousOnlyOperation
============================================================================ short test summary info =============================================================================
ERROR lala/playwright/create_testdata_add_address_order_chili_test.py::test_it[chromium] - django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async ...
==


It works, if I create the page object like this:

def test_it(live_server):
    os.environ['DEBUG']='pw:api'
    with sync_playwright() as playwright:
        run_test_id(live_server, playwright)

def run_test_id(live_server, playwright):
    browser = playwright.webkit.launch(headless=False)
    context = browser.new_context()
    page = context.new_page()
    page.goto(live_server.url)

Any hint how to solve this?

pytest-xdist crashes tests

Running tests with pytest-xdist in parallel doesn't correctly clean up the test-results folder and crashes the tests. Don't know if this can be fixed from playwright-pytest or pytest-xdist instead

issues on upgrade from 0.0.10 -> 0.0.12

Hi there, couple of (hopefully small) issues :)

 browser = getattr(playwright, browser_name).launch(**launch_options)
E       TypeError: launch() got an unexpected keyword argument 'slowMo'

Also

page.wait_for_response('**/api/1.0/blah*')
E       AttributeError: 'Page' object has no attribute 'wait_for_response'

quick 5s debugging..

page.__class__
<class 'playwright.sync_api._generated.Page'>

(Pdb) dir(page)

[..., 'wait_for_event', 'wait_for_function', 'wait_for_load_state', 'wait_for_selector', 'wait_for_timeout', 'workers']

Cheers~

[Question]: Testing on different resolution

Your question

Hi amazing people,

I want to check if there is a good way that you can suggest for me to test the same test cases but multiple browsers and resolutions.
I am using the Page Object Model that is suggested here: https://playwright.dev/python/docs/pom
along with that I utilise pytest-playwright library to write my tests.

Currently, what I understood is that I can only override the browser context for each of the Test Case file, for example:

import pytest
from playwright.sync_api import Page
from page_objects import Homepage

# conftest.py
@pytest.fixture(scope="session")
  def browser_context_args(browser_context_args):
  return {
      **browser_context_args,
      "viewport": {
          "width": 1920,
          "height": 1080,
      }
  }

class TestHomepage1:
    @pytest.fixture(autouse=True)
    def setup(self, page: Page):
        self.page = page
        self.homepage = Homepage(page)
        self.homepage.navigate()

    def test_valid_homepage(self):
        visible = self.homepage.validate_visibility()
        assert visible

But in case I would like to run the "TestHomepage1" on different browser/devices, is there a way for me to describe the configuration on different test run?

What I thought of was:

  1. Create different test cases with different configuration (I would like to avoid this as the test cases would be repetitive and hard to maintain)
  2. To create a config file to specify the pytest-playwright run (I can't seem to find any docs if I am using pytest... was thinking of a file like playwright.config.ts - https://playwright.dev/python/docs/test-configuration/)
  3. I need help from you guys T_T let me know what you guys think!

*first post here, I am a beginner in Python too, so please be gentle to me xD

[QUESTION] How to use two separate browser contexts using provided fixture and not to loose the CLI arguments?

I have a common case of first authorised user creates 'issue', second authorised user should 'approve' it.
I don't wont to logout with the first user because login procedure time is quite long.

I hoped to create separate browser.context for the second user but i'm not sure how to do that correctly using the fixtures provided, as according to the rules of pytest they are used only once and so I'm not able to use context or page fixtures because they already have context created, but if I go one level highter to Browser fixture I totally loose the provided ability to use CLI arguments, such as --tracing. And this is the main reason to use the plugin itself.

https://github.com/microsoft/playwright-pytest/issues/44 example doesn't help because wihile it does create several browsers, CLI arguments are not working as it is using higher level Browser fixture
Tried to Google for several hours but couldn't find any examples, could anyone please provide me with some?

[FEATURE] Expose Playwright async/await flavor

I need to run aiohttp server and use playwright in tests at the same time.
Am I right that pytest-playwright right now can't help me with that?

It provides fixtures only for sync API. But I need async API.
So I have to do something like that.

from aiohttp import web
from playwright.async_api import async_playwright

async def index_html(request):
    return web.Response(body="<html><body>Hello world</body></html>", content_type="text/html")

async def test_without_page_fixture_passes(aiohttp_server):
    app = web.Application()
    app.router.add_get("/", index_html)
    server = await aiohttp_server(app)
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto(str(server.make_url("/")))
        assert await page.text_content("body") == "Hello world"

[pytest-bdd] def browser_type -- getattr(): attribute name must be string

Hi there. Thanks a lot for the plugin!
Would like to try it with pytest-bdd, however got the following error:

    @pytest.fixture(scope="session")
    def browser_type(playwright: Playwright, browser_name: str) -> BrowserType:
>       return getattr(playwright, browser_name)
E       TypeError: getattr(): attribute name must be string

related step definition:

@given("test_playwright")
def test_playwright(page):
    pass

env:

Python: 3.9.0, 
Packages: {'pytest': '6.2.2', 'py': '1.10.0', 'pluggy': '0.13.1'}, 
Plugins:  Faker-6.5.0, progress-1.2.2, base-url-1.4.2, bdd-4.0.2, xdist-2.2.1, metadata-1.11.0, playwright-0.1.1, repeat-0.9.1, forked-1.3.0, allure-pytest-bdd-2.8.36, rerunfailures-10.0
^```

please advise
thanks!

video size 0KB on windows 10

command:
pytest -k test_bucket_info --video on --screenshot on -vv -s

when done, video's size is 0KB

image

and, another question: does the tempfile.TemporaryDirectory works well on windows 10?

thanks.

How to open two pages?

browser = playwright.chromium.launch()
context = browser.new_context()
page0 = context.new_page()
page = context.new_page()

How to open two pages using pytest?
Thank you!

[FEATURE] Allow attaching screenshot and video into Allure report

I usually use Allure report with PyTest+Playwright.

Test code (intented to fail)

from playwright.sync_api import Page


def test_github_search(page: Page):
    page.goto('https://github.com/')
    page.focus('input[name="q"]')
    page.keyboard.type('playwright')
    with page.expect_navigation():
        page.keyboard.press('Enter')
    first_item = page.query_selector_all('.repo-list-item')[0]
    assert 'Playwright' in first_item.text_content()

Motivation

I want to store the video for failed tests.
I don't want to keep sitting at the laptop for observing flaky test failure :)

So I used to attach video into Allure report.
https://zenn.dev/yusukeiwaki/articles/cfda648dc170e5#%E3%83%86%E3%82%B9%E3%83%88%E5%A4%B1%E6%95%97%E6%99%82%E3%81%AE%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AB%E5%8B%95%E7%94%BB%E3%82%92%E6%B7%BB%E4%BB%98%E3%81%99%E3%82%8B (Sorry in Japanese)

image

When we handle a lot of test cases, it is useful to put screenshot and video into Allure report (not in test-report directory), because it is really hard to find the video file from a list of many files for each failure.

Problem

#70 brought very useful feature. Thank you :)

However it doesn't put video and screenshots into Allure report as attachments.
For putting them into Allure report, we still have to write the script like below.

from playwright.sync_api import Page
import pytest
import allure
from slugify import slugify


def pytest_runtest_makereport(item, call) -> None:
    if call.when == "call":
        if call.excinfo is not None and "page" in item.funcargs:
            page: Page = item.funcargs["page"]

            # ref: https://stackoverflow.com/q/29929244
            allure.attach(
                page.screenshot(type='png'),
                name=f"{slugify(item.nodeid)}.png",
                attachment_type=allure.attachment_type.PNG
            )

            video_path = page.video.path()
            page.context.close()  # ensure video saved
            allure.attach(
                open(video_path, 'rb').read(),
                name=f"{slugify(item.nodeid)}.webm",
                attachment_type=allure.attachment_type.WEBM
            )


@pytest.fixture()
def browser_context_args(browser_context_args, tmpdir_factory: pytest.TempdirFactory):
    return {
        **browser_context_args,
        "record_video_dir": tmpdir_factory.mktemp('videos')
    }

Feature Request

Attach screenshot and videos into Allure report when --alluredir is specified (of cource only when --video=on/retain-on-failure or --screenshot=on/retain-on-failure is specified)

[BUG] Running PyTest in a low version of PyTest may lead to errors “AttributeError: module 'pytest' has no attribute 'FixtureRequest'“

@pytest.fixture
def context(
    browser: Browser,
    browser_context_args: Dict,
    pytestconfig: Any,
    request: pytest.FixtureRequest,
) -> Generator[BrowserContext, None, None]:
    pages: List[Page] = []
    context = browser.new_context(**browser_context_args)
    context.on("page", lambda page: pages.append(page))

    tracing_option = pytestconfig.getoption("--tracing")
    capture_trace = tracing_option in ["on", "retain-on-failure"]
    if capture_trace:
        context.tracing.start(
            name=slugify(request.node.nodeid),
            screenshots=True,
            snapshots=True,
        )
def _build_artifact_test_folder(
    pytestconfig: Any, request: pytest.FixtureRequest, folder_or_file_name: str
) -> str:
    output_dir = pytestconfig.getoption("--output")
    return os.path.join(output_dir, slugify(request.node.nodeid), folder_or_file_name)

In python3.9+,pytest no longer exists ‘FixtureRequest’
If the ‘FixtureRequest’ is changed to ‘fixture’, it is used normally

docs: add example to the "Customizing fixture options" section (e.g. for browser_context_args)

Hi, I'm complete new to pytest/playwright and have only small experiences with pytohn.
That means, my question is propably more a general syntax/understanding problem as a playwright issue. But hopefully somebody wants to help anyway :-)

I want to create some tests for a site with a self-signed certificate, so I need to pass the "ignoreHTTPSErrors=True" option.
At the moment, I use this (as a workaround):

def test_invalid_user_login(browser):
    context=browser.newContext(ignoreHTTPSErrors=True)
    page=context.newPage()
    login(page,username="invaliduser",password="validpassword")

This works, but would require too redundant line per test. Not a big problem, but I think not the best solution.

From the README.MD, I got this information:

browser_context_args: Override the options for browser.newContext(). It should return a Dict.

Which sound exactly what I need. But all ways I tried, I got still an certificate error --> ignoreHTTPSErrors=True is not used.
FAILED test_1.py::test_normal_login[chromium] - playwright.helper.Error: net::ERR_CERT_AUTHORITY_INVALID at http://10.10.10.10/
Can give somebody me a correct example, how to set/use this fixture?

Thanks a lot

How to reduce the default browser timeout?

I tried a couple of things in my conftest.py file like:

import pytest


@pytest.fixture(scope="session")
def browser_type_launch_args(browser_type_launch_args):
    seconds = 2
    return {**browser_type_launch_args, "timeout": seconds * 1000}

But it doesn't look to be effective, I'm probably missing something, even reading the source code.

My intended goal is to fail test faster than the default 30 seconds to wait for a selector.

Misleading error message on missing browsers

In the case where someone forgets to run python -m playwright install, the pytest plugin throws a misleading error: "Can only run one Playwright at a time."

Came up while debugging this: savvagen/playwright-pytest-example#1

launch_browser = <function launch_browser.<locals>.launch at 0x110b58cb0>

    @pytest.fixture(scope="session")
    def browser(launch_browser: Callable[[], Browser]) -> Generator[Browser, None, None]:
>       browser = launch_browser()

../../../.local/share/virtualenvs/playwright-pytest-example-xdVUjRxZ/lib/python3.7/site-packages/pytest_playwright/pytest_playwright.py:113: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../.local/share/virtualenvs/playwright-pytest-example-xdVUjRxZ/lib/python3.7/site-packages/pytest_playwright/pytest_playwright.py:97: in launch
    pw = sync_playwright().start()
../../../.local/share/virtualenvs/playwright-pytest-example-xdVUjRxZ/lib/python3.7/site-packages/playwright/__init__.py:34: in sync_playwright
    return SyncPlaywrightContextManager()
../../../.local/share/virtualenvs/playwright-pytest-example-xdVUjRxZ/lib/python3.7/site-packages/playwright/main.py:81: in __init__
    self._connection = run_driver()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

    def run_driver() -> Connection:
        loop = asyncio.get_event_loop()
        if loop.is_running():
>           raise Error("Can only run one Playwright at a time.")
E           playwright.helper.Error: Can only run one Playwright at a time.

[FEATURES] Make playwright-pytest more feature rich

This is tracking issue to make playwright-pytest more feature rich as like the new playwright test runner in js/ts world.
Planned features:

  • Device emulation support from cli #61
  • Screenshot support out of box #70
  • Video support #70
  • Tracing support #70
  • Context Storage Support

specify full-size mode in browser

Hello!
When I try to run this code

def test_is_chromium(page,
                     browser_context_args={
                         "locale": 'en-US',
                         "viewport": {"width": 2560, "height": 1440}
                        }):
    page.goto("https://www.google.com/")

Chromium opens, but it doesn't change it's size

[Question] Could not combine Pytest-BDD with playwright pytest plugin

Context:

  • Playwright Version: 1.11.1-1621490832000
  • Operating System: MacOS
  • Python Version: 3.9

Could someone help to figure out the issue? I couldn't use Pytest-BDD with Playwright pytest plugin, it throws the error below:

_playwright = <playwright._impl._playwright.Playwright object at 0x7f8a881d14c0>, browser_name = None
@pytest.fixture(scope="session")
def browser_type(playwright: Playwright, browser_name: str) -> BrowserType:

  return getattr(playwright, browser_name)

E TypeError: getattr(): attribute name must be string_

This is my feature file:

Feature: Create citizen complaint

Scenario: Testing Google
Given I login to Google`

And this is my step definitions:

from pytest_bdd import scenario, given, when, then

@Scenario('../scenarios/login-page.feature', 'Testing Google')
def test_google():
pass

@given('I login to Google')
def login(page):
page.goto('https://www.google.com.vn')

[BUG] Screenshot capture only-on-failure crashes if an exception is raised during setup

Trace:

        screenshot_option = pytestconfig.getoption("--screenshot")
        capture_screenshot = screenshot_option == "on" or (
>               request.node.rep_call.failed and screenshot_option == "only-on-failure"
        )
E       AttributeError: 'Function' object has no attribute 'rep_call'

The issue stems from the pytest_runtest_makereport hook

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item: Any) -> Generator[None, Any, None]:
    # execute all other hooks to obtain the report object
    outcome = yield
    rep = outcome.get_result()

    # set a report attribute for each phase of a call, which can
    # be "setup", "call", "teardown"

    setattr(item, "rep_" + rep.when, rep)

During execution of a test, this hook once each for setup, call, and teardown. When a test has completed, the item will have 3 attributes: rep_setup, rep_call, rep_teardown

If execution halts due to an exception within a fixture before the test code is executed, then the item will only have a rep_setup attribute. So the following line, which checks for node.rep_call, fails:

        capture_screenshot = screenshot_option == "on" or (
            request.node.rep_call.failed and screenshot_option == "only-on-failure"
        )

There are a couple of ways I thought of to solve this:

  1. Perform a cascading check for reach rep_x attribute and retrieve the failed attribute from the latest one.
  2. If the only use for the report is to check the failure state of the current test loop regardless of phase, then the report hook could be modified like so:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item: Any) -> Generator[None, Any, None]:
    # execute all other hooks to obtain the report object
    outcome = yield
    # Set a report attribute for the latest phase of the call, which can
    # be "setup", "call", "teardown
    item.report = outcome.get_result()

and then modify the capture_screenshot check in the context yield:

        capture_screenshot = screenshot_option == "on" or (
            request.node.report.failed and screenshot_option == "only-on-failure"
        )

Let me know if you need any more info.

How to reuse authentication state in playwright-pytest?

I've got a post login authentication status,And saved in "d:\abc.json".
How to reuse this authentication status in pytest (login free)?
#========The following are the commands used in repl======
from playwright.sync_api import sync_playwright
playwright = sync_playwright().start()
browser = playwright.chromium.launch(headless=False)
page = browser.new_page()
page.goto(url)
page.fill("#userName1",name);page.fill("#password1",pasd);page.click("#btnLogin")
storage=context.storage_state(path='d:/abc.json')

#In the future, you will not need to log in and open the internal web page directly
context = browser.new_context(storage_state='d:/abc.json')
page =context.new_page()
page.goto(...)

How to use abc.json in pytest???Thank you very much
I just learned playwright-python, please give an example of how to use it, thank you!
#for example
def test_xinxibiao(page,context):
page = context.new_page()

Error running pre-commit with mypy

When running pre-commit, mypy fails:

Trim Trailing Whitespace.................................................Passed
Fix End of Files.........................................................Passed
Check Yaml...............................................................Passed
Check for added large files..............................................Passed
black....................................................................Passed
mypy.....................................................................Failed
- hook id: mypy
- exit code: 1

tests/assets/django/settings.py:16: error: Need type annotation for 'ALLOWED_HOSTS' (hint: "ALLOWED_HOSTS: List[<type>] = ...")
tests/assets/django/urls.py:2: error: Module 'django.urls' has no attribute 'path'
Found 2 errors in 2 files (checked 8 source files)

flake8...................................................................Passed

Issue with --tracing

Hi

When I add in --tracing to the CLI arguments I get the following error:

ERROR: usage: pytest [options] [file_or_dir] [file_or_dir] [...]
pytest: error: unrecognized arguments: --tracing
inifile: /Users/marklane/Code/Evertime_playwright/pytest.ini
rootdir: /Users/marklane/Code/Evertime_playwright

I have tried adding this to the purest.ini file also but the same issue occurs

pytest --headed stopped working in 0.2.0

The --headed argument does not open a browser when using pytest-playwright 0.2.0

pip install -U pytest-playwright==0.2.0
pytest --headed <test>   # No browser visible
pip install -U pytest-playwright==0.1.0
pytest --headed <test>   # browser is in headed mode
pip install -U pytest-playwright==0.2.0
pytest --headed <test>   # No browser visible

Adding
launch_args['headless'] = False in browser_type_launch_args works fine and the browser opens in headed mode even with 0.2.0

pytest django SynchronousOnlyOperation

I am trying the simplest scenario without pytest-playwright plugin.

import pytest
from playwright import sync_playwright

@pytest.mark.django_db
def test_p(live_server):
    playwright = sync_playwright().start()
    browser = playwright.chromium.launch()
    page = browser.newPage()
    page.goto(f"{live_server.url}")
    page.close()

And I am getting the following error

django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.

addCookie

如何加载cookie 实现免登陆

[BUG] Playwright produces zero-bytes .webm videos

Context:

  • Playwright Version: Version 1.15.0-1631797286000
  • Operating System: ubuntu/bionic64
  • Node.js version: v12.16.1
  • Browser: All
  • Extra: running inside virtualbox vm, host OS is Windows 10.

Code Snippet

@pytest.fixture(autouse=True)
def browser_context_args(browser_context_args: dict) -> dict:

    browser_context_args = {
        **browser_context_args,
        "viewport": {
            "width": 1920,
            "height": 1080,
        },
        "device_scale_factor": 2,
        "record_video_size": {
            "width": 800,
            "height": 600,
        },
    }

    return browser_context_args

Describe the bug

I am running Playwright + Python + pytest-playwright with following arguments:

pytest --tracing retain-on-failure --screenshot only-on-failure --video retain-on-failure

On error, tracing and screenshots are saved fine, however videos come out as zero bytes .webm files.

Error when running Django tests under pytest - fixture 'browser_name' not found

Hi,
I'm starting with both pytest and playwright so maybe this error could be expected in my situation.

I have a Django project with almost 900 Django tests. I would like to start using pytest and playwright for some of the new tests so it's necessary the whole test suite can be run under pytest. It worked until I installed pytest-playwright. Since it was installed, every Django test that's not written as a pytest one fails with

file /src/myproject/myproject/app/tests/test_exam.py, line 45
      def test_exam_list(self):
file /usr/local/lib/python3.8/site-packages/pytest_playwright/pytest_playwright.py, line 61
  @pytest.fixture(autouse=True)
  def skip_browsers(request: Any, browser_name: str) -> None:
E       fixture 'browser_name' not found
>       available fixtures: _UnitTestCase__pytest_class_setup, _dj_autoclear_mailbox, _django_clear_site_cache, _django_db_marker, _django_set_urlconf, _django_setup_unittest, _fail_for_invalid_template_variable, _live_server_helper, _session_faker, _template_string_if_invalid_marker, _verify_url, admin_client, admin_user, base_url, browser, browser_context_args, browser_type_launch_args, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, celery_app, celery_config, celery_enable_logging, celery_includes, celery_parameters, celery_session_app, celery_session_worker, celery_worker, celery_worker_parameters, celery_worker_pool, class_mocker, client, context, cov, db, depends_on_current_app, django_assert_max_num_queries, django_assert_num_queries, django_db_blocker, django_db_createdb, django_db_keepdb, django_db_modify_db_settings, django_db_modify_db_settings_parallel_suffix, django_db_modify_db_settings_tox_suffix, django_db_modify_db_settings_xdist_suffix, django_db_reset_sequences, django_db_setup, django_db_use_migrations, django_mail_dnsname, django_mail_patch_dns, django_test_environment, django_user_model, django_username_field, doctest_namespace, event_loop, factoryboy_request, faker, is_chromium, is_firefox, is_webkit, launch_browser, live_server, mailoutbox, mocker, module_mocker, monkeypatch, no_cover, package_mocker, page, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, rf, session_mocker, settings, skip_browsers, testrun_uid, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory, transactional_db, use_celery_app_trap, worker_id
>       use 'pytest --fixtures [testpath]' for help on them.

I have one pytest+playwright test that uses the page fixture on the same project and it works fine.

I tried to pip uninstall pytest-playwright and after that, the test suite can be run successfully (except the test using page fixture of course) so the issue seems to be caused by pytest-playwright installed. Am I missing something?

Thanks

Persistent context example throws a ScopeMismatch exception

Using pytest-playwright 0.1.1 with playwright 1.11.0, I used to be able to create a persistent context like shown below -

import pytest

from playwright.sync_api import Playwright

from typing import Dict

@pytest.fixture(scope="session")
def context(
    playwright: Playwright,
    browser_name: str,
    browser_type_launch_args: Dict,
    browser_context_args: Dict
):
    context = getattr(playwright, browser_name).launch_persistent_context("./foobar", **{
        **browser_type_launch_args,
        **browser_context_args
    })

    context.set_default_navigation_timeout(90000)
    context.set_default_timeout(90000)

    yield context
    context.close()

def test_example(page):
    page.goto("https://example.com")
    assert page.inner_text('h1') == 'Example Domain'
    page.click("text=More information")

I recently upgraded to pytest-playwright 0.2.0 and playwright 1.14.1, and took the persistent context snippet published on https://playwright.dev/python/docs/test-runners#persistent-context to understand how it's done on the latest version. Unfortunately the snippet seems to throw a ScopeMismatch error, because browse_context_args has function scope -

# conftest.py
import pytest
from playwright.sync_api import BrowserType
from typing import Dict


@pytest.fixture(scope="session")
def context(
    browser_type: BrowserType,
    browser_type_launch_args: Dict,
    browser_context_args: Dict
):
    context = browser_type.launch_persistent_context("./foobar", **{
        **browser_type_launch_args,
        **browser_context_args,
        "locale": "de-DE",
    })
    yield context
    context.close()


def test_example(page):
    page.goto("https://example.com")
    assert page.inner_text('h1') == 'Example Domain'
    page.click("text=More information")

Sample Output:

$ pytest .
========================================================================================== test session starts ==========================================================================================
platform win32 -- Python 3.9.6, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: C:\Users\fowliena\Documents\repositories\persistentcontext
plugins: asyncio-0.15.1, base-url-1.4.2, forked-1.3.0, json-report-1.4.0, metadata-1.11.0, playwright-0.2.0, xdist-2.2.1
collected 1 item

test_stuff.py E                                                                                                                                                                                    [100%]

================================================================================================ ERRORS =================================================================================================
________________________________________________________________________________ ERROR at setup of test_example[chromium] ________________________________________________________________________________
Exception ignored in: <function BaseSubprocessTransport.__del__ at 0x0000011E28530DC0>
Traceback (most recent call last):
  File "c:\users\fowliena\appdata\local\programs\python\python39\lib\asyncio\base_subprocess.py", line 126, in __del__
    self.close()
  File "c:\users\fowliena\appdata\local\programs\python\python39\lib\asyncio\base_subprocess.py", line 104, in close
    proto.pipe.close()
  File "c:\users\fowliena\appdata\local\programs\python\python39\lib\asyncio\proactor_events.py", line 108, in close
    self._loop.call_soon(self._call_connection_lost, None)
  File "c:\users\fowliena\appdata\local\programs\python\python39\lib\asyncio\base_events.py", line 746, in call_soon
    self._check_closed()
  File "c:\users\fowliena\appdata\local\programs\python\python39\lib\asyncio\base_events.py", line 510, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
ScopeMismatch: You tried to access the 'function' scoped fixture 'browser_context_args' with a 'session' scoped request object, involved factories
test_stuff.py:7:  def context(browser_type: playwright.sync_api._generated.BrowserType, browser_type_launch_args: Dict, browser_context_args: Dict)
..\..\..\appdata\local\programs\python\python39\lib\site-packages\pytest_playwright\pytest_playwright.py:135:  def browser_context_args(pytestconfig: Any, playwright: playwright.sync_api._generated.Playwright, device: Optional[str]) -> Dict
======================================================================================== short test summary info ========================================================================================
ERROR test_stuff.py::test_example[chromium]

Is this due to the snippet being incorrect, or am I missing something with the way I'm creating a persistent context?

I'm running Python 3.9.6, with the following packages installed -

$ pip list installed
Package                    Version
-------------------------- ---------
apipkg                     1.5
atomicwrites               1.4.0
attrs                      21.2.0
autopep8                   1.5.6
certifi                    2020.12.5
chardet                    4.0.0
click                      8.0.1
colorama                   0.4.4
coverage                   5.5
execnet                    1.8.1
flake8                     3.9.1
flake8-docstrings          1.6.0
flake8-import-order        0.18.1
flake8-junit-report        2.1.0
flake8-polyfill            1.0.2
future                     0.18.2
gitdb                      4.0.7
GitPython                  3.1.18
greenlet                   1.1.0
hvac                       0.10.10
idna                       2.10
iniconfig                  1.1.1
Jinja2                     2.11.3
joblib                     1.0.1
livereload                 2.6.3
lunr                       0.5.8
Markdown                   3.3.4
MarkupSafe                 2.0.1
mccabe                     0.6.1
mkdocs                     1.1.2
mkdocs-autorefs            0.2.1
mkdocs-gen-files           0.3.3
mkdocs-material            7.1.6
mkdocs-material-extensions 1.0.1
mkdocstrings               0.15.1
mypy                       0.910
mypy-extensions            0.4.3
nltk                       3.6.2
packaging                  20.9
pathspec                   0.8.1
pep8-naming                0.11.1
pip                        21.1.3
playwright                 1.14.1
pluggy                     0.13.1
py                         1.10.0
pycodestyle                2.7.0
pydocstyle                 6.0.0
pyee                       8.1.0
pyflakes                   2.3.1
pygit                      0.1
Pygments                   2.9.0
pymdown-extensions         8.2
pyparsing                  2.4.7
pytest                     6.2.3
pytest-asyncio             0.15.1
pytest-base-url            1.4.2
pytest-forked              1.3.0
pytest-json-report         1.4.0
pytest-metadata            1.11.0
pytest-playwright          0.2.0
pytest-xdist               2.2.1
python-slugify             5.0.2
pytkdocs                   0.11.1
PyYAML                     5.4.1
regex                      2021.4.4
requests                   2.25.1
semver                     2.13.0
setuptools                 56.0.0
six                        1.16.0
smmap                      4.0.0
snowballstemmer            2.1.0
tblib                      1.7.0
text-unidecode             1.3
toml                       0.10.2
tornado                    6.1
tqdm                       4.61.0
typed-ast                  1.4.3
typing-extensions          3.10.0.0
urllib3                    1.26.4
websockets                 9.0.1
yamllint                   1.26.1

[FEATURE] Config file support

Same thing as in js/ts world playwright.config.ts equivalent for python playwright.conf.py which would automatically parameterize all the tests.

Includes #67

--browser-channel="chrome" is passed to all browsers if multiple are used in a test run

Use case:
I want to run all tests with all browsers, and I want to run tests with Chrome instead of Chromium
to do that I'm using a combination of run parameters like:

pytest --browser=chromium --browser=firefox -browser=webkit --browser-channel=chrome

This yields errors like:
Unsupported firefox channel "chrome"
Unsupported webkit channel "chrome"

Possible solution for that would be to check what type of browser and browser-channel are passed in launch_browser fixture
#78

Broken screenshot in pytest playwright html report

  • Playwright Version: [0.2.3]
  • Operating System: [Mac]
  • Python version: [3.9]
  • Browser: [Chromium]
  • Extra: [pytest version == 7.0.1]
  • conftest.py file
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
    pytest_html = item.config.pluginmanager.getplugin("html")
    outcome = yield
    screen_file = ''
    report = outcome.get_result()
    extra = getattr(report, "extra", [])
    if report.when == "call" or report.when == "setup":
        if report.failed and "page" in item.funcargs:
            page = item.funcargs["page"]
            screenshot_dir = "/screenshots"
            screen_file = (screenshot_dir + f"{slugify(item.nodeid)}.png")
            page.screenshot(path=screen_file, full_page=True)
        if report.failed:
            # add the screenshots to the html report
            extra.append(pytest_html.extras.png(screen_file))
        report.extra = extra

Screen Shot 2022-03-10 at 1 37 37 PM

context fixture

Hi,

I'm looking for an example on how to use the context fixture. My goal is to parametrize a test with different devices. Is this possible with the pytest-playwright plugin ?

[pylint] redefined-outer-name error using fixture exampled

Hi, it's me again :-)

I used the example about disabling HTTPS checks and it works great, but I think there may be an issue which can become a bug in more complex environments.

Whats from README.MD

import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
    return {
        **browser_context_args,
        "ignoreHTTPSErrors": True
    }

and whats from https://docs.pytest.org/en/latest/reference.html#pytest-fixture:

name – The name of the fixture. This defaults to the name of the decorated function. If a fixture is used in the same module in which it is defined, the function name of the fixture will be shadowed by the function arg that requests the fixture; one way to resolve this is to name the decorated function fixture_ and then use @pytest.fixture(name='').

I can't judge if this may become a problem or not, but at least pylint is complaining about that.
Maybe the example should get a node about that or changed.

@pytest.fixture(name='browser_context_args', scope="session")
def fixture_browser_context_args(browser_context_args):
    """disable cert check"""
    return {
        **browser_context_args,
        "ignoreHTTPSErrors": True
        }

[FEATURE] Run Browser once in TestClass

Hi!
I have the following code:

class TestClass:
    def test_a(self, page):
        print("open site")
        self.page = page
        self.page.goto("https://microsoft.com")
    
    def test_b(self, page):
        print("check title of site")
        self.page = page
        page_title = self.page.title()#
        assert page_title == "Microsoft - Official Home Page"

The question is - how can I run browser once for 2 tests? Sequence should be the following - browser is starting, test_a is executing, then test_b is executing, then browser is closing.

artifacts_folder FileNotFoundError in combination with pytest-parallel

A FileNotFoundError is thrown during the test cleanup phase. This error has no impact on the result. I tracked the issue down to the tempfile.TemporaryDirectory artifacts_folder. The TemporyDirectory is explicitly cleaned with a cleanup() call. It is also implicitly cleaned up when the object is garbage-collected or during interpreter shutdown.

I'm not sure how pytest-parallel works. I think at some point the process is forked. This creates multiple TemporaryDirectory instances and thus multiple clean up attempts? In Python 3.10 these errors can easily be ignored using the TemporaryDirectory ignore_cleanup_errors kwarg. Not sure how it should be handled in Python 3.7.

Successful Test Traceback:

Traceback (most recent call last):
  File "/usr/lib/python3.7/weakref.py", line 648, in _exitfunc
    f()
  File "/usr/lib/python3.7/weakref.py", line 572, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
  File "/usr/lib/python3.7/tempfile.py", line 936, in _cleanup
    _rmtree(name)
  File "/usr/lib/python3.7/shutil.py", line 485, in rmtree
    onerror(os.lstat, path, sys.exc_info())
  File "/usr/lib/python3.7/shutil.py", line 483, in rmtree
    orig_st = os.lstat(path)
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/playwright-pytest-7rzu1l9o'

Tests are parameterized even if not using playwright fixtures

Tests are parameterized that don't use playwright fixtures. For example, given these tests:

def test_page(page):
    print("page")

def test_other():
    print("other")

I get this output from a vanilla test run:

% pytest test.py --verbose
=============================== test session starts ===============================
platform darwin -- Python 3.8.1, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- .pyenv/versions/3.8.1/envs/playwright-test/bin/python3.8
cachedir: .pytest_cache
rootdir: ...
plugins: base-url-1.4.2, playwright-0.0.8
collected 2 items

tests/test.py::test_page[chromium] PASSED                                   [ 50%]
tests/test.py::test_other[chromium] PASSED                                  [100%]

================================ 2 passed in 0.68s ================================

And this output from a multi-browser test:

% pytest test.py --verbose --browser chromium --browser firefox
=============================== test session starts ===============================
platform darwin -- Python 3.8.1, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- .pyenv/versions/3.8.1/envs/playwright-test/bin/python3.8
cachedir: .pytest_cache
rootdir: ...
plugins: base-url-1.4.2, playwright-0.0.8
collected 4 items

tests/test.py::test_page[chromium] PASSED                                   [ 25%]
tests/test.py::test_other[chromium] PASSED                                  [ 50%]
tests/test.py::test_page[firefox] PASSED                                    [ 75%]
tests/test.py::test_other[firefox] PASSED                                   [100%]

================================ 4 passed in 3.12s ================================

I didn't expect test_other to be parameterized as test_other[chromium] in the first scenario, or called twice in the second scenario.

I think it's because this line in pytest_generate_tests isn't working as intended:

if "browser_name" in metafunc.fixturenames:

In fact bother "browser_name" and "skip_browsers" are guaranteed to be in metafunc.fixturenames, because skip_browsers is defined as autouse and pulls in browser_name. Things work as I expect if I comment out the autouse decorator on skip_browsers.

I'm not quite sure if this is a bug or working as intended. For my usecase I'd rather that this plugin not touch tests that don't use its fixtures, so I can add an integration test to a project with hundreds of existing tests. But I might be misunderstanding how it's supposed to work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.