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

Andrew/precommit #173

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .github/actions/action.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
# not using this until actions supports timeout-minutes
name: 'common-test-fragment'
description: 'Run python common across OSes'
Expand All @@ -8,12 +9,15 @@ runs:
steps:
- name: Install devtools
run: pip install .[dev]

- name: DTDoctor
run: dtdoctor
#timeout-minutes: 3
# timeout-minutes: 3

- name: Test Process Control
run: pytest -vv -rA tests/test_process.py
#timeout-minutes: 1
# timeout-minutes: 1

- name: Test the Rest
run: pytest -vv -rA --ignore=tests/test_process.py
#timeout-minutes: 1
# timeout-minutes: 1
1 change: 1 addition & 0 deletions .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
name: ruff-wf
on: pull_request
jobs:
Expand Down
115 changes: 31 additions & 84 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,95 +1,42 @@
---
name: test-wf

on: pull_request
jobs:
test-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v1 # Would be nice to bump this? Regressions.
- name: Install Dependencies
run: sudo apt-get update && sudo apt-get install chromium-browser xvfb
timeout-minutes: 4 # because sometimes it dies
#- uses: ./.github/actions/ # it would be nice but it doesn't support timeout-minutes
- name: Install choreographer
run: pip install .[dev]
- name: DTDoctor
run: dtdoctor --no-run
timeout-minutes: 1
- name: Test Process Control DEBUG
if: runner.debug
run: xvfb-run pytest -W error -vv -rA --capture=tee-sys tests/test_process.py
timeout-minutes: 5
- name: Test Process Control
if: ${{ ! runner.debug }}
run: xvfb-run pytest -W error -n auto -v -rfE --capture=fd tests/test_process.py
timeout-minutes: 2
- name: Test The Rest
if: ${{ ! runner.debug }}
run: pytest -W error -n auto -v -rfE --ignore=tests/test_process.py
timeout-minutes: 2
- name: Test The Rest DEBUG
if: runner.debug
run: pytest -W error -vvv -rA --capture=tee-sys --ignore=tests/test_process.py
timeout-minutes: 5
test-windows:
runs-on: windows-latest
test-all:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"

- name: Install Dependencies
run: choco install googlechrome -y --ignore-checksums
timeout-minutes: 4 # because sometimes it dies
#- uses: ./.github/actions/
- name: Install choreographer
run: pip install .[dev]
- name: DTDoctor
run: dtdoctor --no-run
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get update && sudo apt-get install xvfb
timeout-minutes: 1
- name: Test Process Control DEBUG
if: runner.debug
run: pytest -W error -vv -rA --capture=tee-sys tests/test_process.py
timeout-minutes: 5
- name: Test Process Control
if: ${{ ! runner.debug }}
run: pytest -W error -n auto -v -rFe --capture=fd tests/test_process.py
timeout-minutes: 2
- name: Test The Rest
if: ${{ ! runner.debug }}
run: pytest -W error -n auto -v -rfE --ignore=tests/test_process.py
timeout-minutes: 2
- name: Test The Rest DEBUG
if: runner.debug
run: pytest -W error -vvv -rA --capture=tee-sys --ignore=tests/test_process.py
timeout-minutes: 5
test-mac:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: Install Dependencies
run: brew install google-chrome
timeout-minutes: 4 # because sometimes it dies
#- uses: ./.github/actions/

- name: Install choreographer
run: pip install .[dev]
- name: DTDoctor
run: dtdoctor --no-run
run: uv sync --all-extras
- name: Install google-chrome-for-testing
run: uv run choreo_get_browser
- name: Diagnose
run: uv run choreo_diagnose --no-run
timeout-minutes: 1
- name: Test Process Control DEBUG
if: runner.debug
run: pytest -W error -vv -rA --capture=tee-sys tests/test_process.py
timeout-minutes: 5
- name: Test Process Control
if: ${{ ! runner.debug }}
run: pytest -W error -n auto -v -rFe --capture=fd tests/test_process.py
timeout-minutes: 4
- name: Test The Rest
if: ${{ ! runner.debug }}
run: pytest -W error -n auto -v -rfE --ignore=tests/test_process.py
timeout-minutes: 3
- name: Test The Rest DEBUG
if: runner.debug
run: pytest -W error -vvv -rA --capture=tee-sys --ignore=tests/test_process.py
timeout-minutes: 5

- name: Test
if: ${{ ! runner.debug && matrix.os != 'ubuntu-latest' }}
run: uv run poe test
timeout-minutes: 7

- name: Test (Linux)
if: ${{ ! runner.debug && matrix.os == 'ubuntu-latest' }}
run: xvfb-run uv run poe test
timeout-minutes: 7

- name: Test (Debug)
if: runner.debug
run: uv run poe debug-test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# specific
browser_exe

# normal stuff
.venv

# ignore build artifacts
Expand Down
94 changes: 94 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
%YAML 1.2
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-case-conflict
- id: check-merge-conflict
- id: check-toml
- id: debug-statements
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma
# alternative: isort
# optional comments: # noreorder
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.14.0
hooks:
- id: reorder-python-imports
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.8.2
hooks:
# Run the linter.
- id: ruff
types_or: [python, pyi]
# Run the formatter.
- id: ruff-format
types_or: [python, pyi]
# options: ignore one line things [E701]
- repo: https://github.com/adrienverge/yamllint
rev: v1.35.1
hooks:
- id: yamllint
name: yamllint
description: This hook runs yamllint.
entry: yamllint
language: python
types: [file, yaml]
args: ['-d', "{\
extends: default,\
rules: {\
colons: { max-spaces-after: -1 }\
}\
}"]
- repo: https://github.com/rhysd/actionlint
rev: v1.7.4
hooks:
- id: actionlint
name: Lint GitHub Actions workflow files
description: Runs actionlint to lint GitHub Actions workflow files
language: golang
types: ["yaml"]
files: ^\.github/workflows/
entry: actionlint
- repo: https://github.com/jorisroovers/gitlint
rev: v0.19.1
hooks:
- id: gitlint
name: gitlint
description: Checks your git commit messages for style.
language: python
additional_dependencies: ["./gitlint-core[trusted-deps]"]
entry: gitlint
args: [--staged, --msg-filename]
stages: [commit-msg]
- repo: https://github.com/crate-ci/typos
rev: v1.28.2
hooks:
- id: typos
- repo: https://github.com/markdownlint/markdownlint
rev: v0.13.0
hooks:
- id: markdownlint
name: Markdownlint
description: Run markdownlint on your Markdown files
entry: mdl --rules ~MD026
language: ruby
files: \.(md|mdown|markdown)$
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
name: Detect secrets
language: python
entry: detect-secrets-hook
args: ['']
48 changes: 23 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ You can also add "--no-headless" to these if you want to see the browser pop up.

### Writing Tests

- Put async and sync tests in different files. Add `_sync.py` to synchronous tests.
- If doing process tests, maybe use the same decorators and fixtures in the `test_process.py` file.
- If doing browser interaction tests, use `test_placeholder.py` as the minimum template.
- Put async and sync tests in different files. Add `_sync.py` to synchronous tests.
- For process tests, use the same decorators/fixtures like `test_process.py` file.
- For API tests, use `test_placeholder.py` as the minimum template.

## Help Wanted

We need your help to test this package on different platforms
and for different use cases.
To get started:

1. Clone this repository.
1. Create and activate a Python virtual environment.
1. Install this repository using `pip install .` or the equivalent.
1. Run `dtdoctor` and paste the output into an issue in this repository.
1. Clone this repository.
1. Create and activate a Python virtual environment.
1. Install this repository using `pip install .` or the equivalent.
1. Run `dtdoctor` and paste the output into an issue in this repository.

## Quickstart with `asyncio`

Expand All @@ -80,18 +80,18 @@ if __name__ == "__main__":

Step by step, this example:

1. Imports the required libraries.
1. Defines an `async` function
1. Imports the required libraries.
1. Defines an `async` function
(because `await` can only be used inside `async` functions).
1. Asks choreographer to create a browser.
1. Asks choreographer to create a browser.
`headless=False` tells it to display the browser on the screen;
the default is no display.
1. Wait three seconds for the browser to be created.
1. Create another tab.
1. Wait three seconds for the browser to be created.
1. Create another tab.
(Note that users can't rearrange programmatically-generated tabs using the mouse,
but that's OK: we're not trying to replace testing tools like [Puppeteer][puppeteer].)
1. Sleep again.
1. Runs the example function.
1. Sleep again.
1. Runs the example function.

See [the devtools reference][devtools-ref] for a list of possible commands.

Expand Down Expand Up @@ -130,23 +130,21 @@ You can use this library without `asyncio`,
my_browser = choreo.Browser() # blocking until open
```

However,
you are responsible for calling `browser.pipe.read_jsons(blocking=True|False)` when necessary
However, you must call `browser.pipe.read_jsons(blocking=True|False)` manually,
and organizing the results.
`browser.run_output_thread()` will start a second thread that constantly prints all responses from the browser,
but it can't be used with `asyncio` and won't play nice with any other read.
In other words,
unles you're really, really sure you know what you're doing,

`browser.run_output_thread()` starts another thread constantly printing
messages received from the browser but it can't be used with `asyncio`
nor will it play nice with any other read.

In other words, unless you're really, really sure you know what you're doing,
use `asyncio`.

## Low-Level Use

We provide a `Browser` and `Tab` interface,
but there is also a lower-level `Target` and `Session` interface that one can use if needed.
We will document these as the API stabilizes.
We provide a `Browser` and `Tab` interface, but there are lower-level `Target`
and `Session` interfaces if needed.

[devtools-ref]: https://chromedevtools.github.io/devtools-protocol/
[kaleido]: https://pypi.org/project/kaleido/
[puppeteer]: https://pptr.dev/


8 changes: 6 additions & 2 deletions choreographer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from .browser import Browser, which_browser
from .browser import Browser
from .browser import get_browser_path
from .browser import which_browser
from .cli_utils import get_browser
from .cli_utils import get_browser_sync

__all__ = [Browser, which_browser]
__all__ = [Browser, get_browser, get_browser_sync, which_browser, get_browser_path]
Loading
Loading