Giter VIP home page Giter VIP logo

playwright-elixir's Introduction

Playwright for Elixir

NOTE: This package is currently in "preview". The features are not yet at parity with other Playwright implementations. Once playwright-elixir is at or near parity with playwright, the version number will be updated to mirror the supported version of playwright.

Overview

Playwright is an Elixir library to automate Chromium, Firefox and WebKit with a single API. Playwright is built to enable cross-browser web automation that is ever-green, capable, reliable and fast. See how Playwright is better.

Installation

The package can be installed by adding playwright to your list of dependencies in mix.exs:

def deps do
  [
    {:playwright, "~> 1.44.0-alpha.1"}
  ]
end

Usage

Example

defmodule Test.ExampleTest do
  use ExUnit.Case, async: true
  use PlaywrightTest.Case

  describe "Navigating to playwright.dev" do
    test "works", %{browser: browser} do
      page = Playwright.Browser.new_page(browser)

      Playwright.Page.goto(page, "https://playwright.dev")
      text = Playwright.Page.text_content(page, ".navbar__title")

      assert text == "Playwright"
      Playwright.Page.close(page)
    end
  end
end

Contributing

Getting started

  1. Clone the repo
  2. Run bin/dev/doctor and for each problem, either use the suggested remedies or fix it some other way
  3. Run bin/dev/test to run the test suite make sure everything is working

Day-to-day

  • Get latest code: bin/dev/update
  • Run tests: bin/dev/test
  • Start server: bin/dev/start
  • Run tests and push: bin/dev/shipit

Building assets for a release

mix assets.build

playwright-elixir's People

Contributors

coreyti avatar dbrody avatar eahanson avatar germsvel avatar jasonwc avatar kianmeng avatar octosteve avatar sax avatar woodward 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

Watchers

 avatar  avatar  avatar  avatar

playwright-elixir's Issues

Default Debug Logging

Currently the default logging is set to debug in dev mode. This causes a LOT of logging output that can get cumbersome to develop with.

The best solution I have found is to do something like this:

config :logger,
  backends: [:console],
  compile_time_purge_matching: [
    [application: :playwright]
  ]

This requires recompiling the dependency: mix deps.compile playwright --force. This may also require any application that uses this to restart as well.

The issue here is there is no way to turn logging on for a portion of the use of playwright-elixir and then off.

I've seen FlexLogger but I dont want to add additional dependencies.

Any ideas?

Better Phoenix.Ecto.SQL.Sandbox setup

Hi!

I managed to get the Phoenix sandbox set up, and wrote about it on my blog. I found that the existing PlaywrightTest.Case module, the Playwright.Browser.new_context function and Playwright.Browser.new_page were not sufficient for my needs so I had to copy and modify them. Maybe this can be improved by changing the library?

As a note, I think it may be better to configure the user-agent header instead of a separate one like I did, but then I think the metadata should be appended to existing user agent that Playwright would use, and I couldn't find a way to read it. Maybe there's a way, or maybe such feature can be requested from upstream. Ideally the user could do either one, by making the library flexible and allowing to configure both the user-agent and additional headers.

Test run failures should not cause subsequent tests to time out.

example:

test/playwright_test.exs:7
** (FunctionClauseError) no function clause matching in Playwright.Browser.new_page/2

The following arguments were given to Playwright.Browser.new_page/2:
    # 1
    {:error, %Playwright.Channel.Error{message: "Timeout 30000ms exceeded."}}
    # 2
    %{}
  
Attempted function clauses (showing 1 out of 1):
  def new_page(%Playwright.Browser{session: session} = browser, options)

stacktrace:
  (playwright 0.1.17-preview-6) lib/playwright/browser.ex:153: Playwright.Browser.new_page/2
  test/playwright_test.exs:3: Playwright.PlaywrightTest.__ex_unit_setup_0/1
  test/playwright_test.exs:1: Playwright.PlaywrightTest.__ex_unit__/2

Response Type Parsing

In the response event, we now have response |> Playwright.Response.body() which works great when the content type is "image/gif" or similar however when the response type is "application/json" or "application/json; charset=utf-8" it seems to hang for me. Not sure if this is something to do with gzip encoding the json content-type. Any recommendations would be helpful.

Event Handle Fill

Hi ๐Ÿ‘‹ ! Thank you for this.

I'm just getting my feet wet with Playwright and your library, so maybe I'm doing something wrong. I noticed that Playwright has an ability to fill an eventhandle, but I do not see that this is exposed by this library.

If there's another way to do what I need to do, please let me know. I'm trying to work within an iframe. I can get the iframe and get the eventhandle from a query and then focus it. But I need to then fill it.

Allow for Page listeners

Is there a way to retrieve listener events for page requests? I see the Page.on/3 and I see it can receive console type events, but what about Request events as per Playwright?

How can I listen to requests?

New function - Abort

Hello,
I would like to ask you about implementation abort function so we can skip some resources to load, especially in my case images and videos.
I made this function here:
https://github.com/geometerio/playwright-elixir/blob/ab729b6f6f1f4f6d9e238d5e97598757b968c548/lib/playwright/route.ex#L14-L15

@spec abort(t(), binary()) :: :ok
  defp abort(%Route{session: session} = route, error_code \\ nil) do
    Channel.post(session, {:guid, route.guid}, :abort, %{error_ode: error_code})
  end

and implementation:

Playwright.Page.route(page_loader, "**/*", fn route, request ->
      if request.resource_type in ["image", "font"] do
        Playwright.Route.abort(route, "blockedbyclient")
      else
        Playwright.Route.continue(route)
      end
    end)

But it crash server, I very new in playwright so not sure where can be problem.

Doc for abort is here and my code is here

[bug] Occasional, non-deterministic test suite timeouts

Something like the following occurs, infrequently. Once this timeout triggers, all following tests fail. This behavior appears to be non-deterministic: mix test --seed <seed> (where <seed> is that from a previous failure) does not force the failure.

  1) test Page .query_selector_all/2 (Test.Features.PageTest)
     test/features/page_test.exs:27
     ** (ExUnit.TimeoutError) test timed out after 60000ms. You can change the timeout:
     
       1. per test by setting "@tag timeout: x" (accepts :infinity)
       2. per test module by setting "@moduletag timeout: x" (accepts :infinity)
       3. globally via "ExUnit.start(timeout: x)" configuration
       4. by running "mix test --timeout x" which sets timeout
       5. or by running "mix test --trace" which sets timeout to infinity
          (useful when using IEx.pry/0)
     
     where "x" is the timeout given as integer in milliseconds (defaults to 60_000).
     
     code: [outer, inner] = Playwright.Page.query_selector_all(page, "css=div")
     stacktrace:
       (stdlib 3.16.1) timer.erl:152: :timer.sleep/1
       (playwright 0.1.1-preview) lib/playwright/page.ex:289: Playwright.Page.hydrate/1
       (elixir 1.12.3) lib/enum.ex:1582: Enum."-map/2-lists^map/1-0-"/2
       test/features/page_test.exs:30: (test)
       (ex_unit 1.12.3) lib/ex_unit/runner.ex:502: ExUnit.Runner.exec_test/1
       (stdlib 3.16.1) timer.erl:166: :timer.tc/1
       (ex_unit 1.12.3) lib/ex_unit/runner.ex:453: anonymous fn/4 in ExUnit.Runner.spawn_test_monitor/4

Dependency on Gun 2.0.0-rc2

When trying to use playwright-elixir in an existing Phoenix project, I get the following dependency error:

Failed to use "gun" (version 2.0.0-rc.2) because
  playwright (version 0.1.16-preview-2) requires ~> 2.0.0-rc.2
  tesla (version 1.4.3) requires ~> 1.3

Gun hasn't had any commits since this RC was cut: https://github.com/ninenines/gun

We should evaluate if we really need to be on this version of Gun

Error message for missing browser executables should be friendlier

A trace example:

** (FunctionClauseError) no function clause matching in Playwright.Browser.new_page/2
    (playwright 1.18.0-alpha.1) lib/playwright/browser.ex:153: Playwright.Browser.new_page({:error, %Playwright.Channel.Error{message: "Executable doesn't exist at <redacted>/chrome-mac/Chromium.app/Contents/MacOS/Chromium"}}, %{})
    <redacted>
    (elixir 1.13.2) lib/task/supervised.ex:89: Task.Supervised.invoke_mfa/2
    (elixir 1.13.2) lib/task/supervised.ex:34: Task.Supervised.reply/4
    (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

Playwright.Keyboard

Before I dive in and try to push Keyboard features, anybody else work on this? I'd hate to duplicate effort. Also, if theres any pointers or suggestions, this would be a good way to track it.

Improve Documentation

Currently the getting started page is blank and the examples are all in test cases. I think improving the documentation could help adoption and use of the package.

Applications using playwright-elixir must independently install playwright js

This adds an extra integration step to every application that tries to use this library.

Ideas:

  • Add documentation about this dependency and how to resolve it.
  • playwright-elixir can ship playwright in its priv directory.
  • This library can check for playwright being installed in the environment, and tell you how to install it.

playwright-assets should be extracted and referenced as a dependency for dev/test

Some work has already been done to extract the test assets to playwright-assets. It would be nice to have that be capable of loading and running as a dependency for this project so that:

  • playwright-assets is usable for other projects. These should not necessarily have to be Elixir projects. So, a standalone server is needed.
  • playwright-assets is able to be independently updated and version-referenced.
  • playwright-elixir is not reported by GitHub to be a project made up mostly of Javascript.

Ports seem to stay open when session is closed

When opening browser via Playwright.BrowserType.launch(:chromium, options) and then closing the browser via Playwright.Browser.close(), the port opened to run chromium seems to stay open.

Seems to stem from within Playwright.Transport when called with Transport.Driver here:
https://github.com/geometerio/playwright-elixir/blob/17abee407e2d5fa30cc42ce62e8017c3d0ae8680/lib/playwright/transport/driver.ex#L18-L22

Even though all the GenServers are started with start_link it doesnt seem to clean up the port.

Decreasing Performance Over Time

In my setup I'm seeing the performance of calls to playwright elixir take longer and longer the more actions are performed. I think it may have to do with callbacks or something? I do have a listener on responses.

It may be my setup but I'm curious if others see this or the best approach to test this issue?

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.