atsfill 0.0.4.dev37__tar.gz → 0.0.4.dev38__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/PKG-INFO +1 -1
  2. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/pyproject.toml +2 -2
  3. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/pyproject.toml.orig +2 -2
  4. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/bamboohr.py +5 -2
  5. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/dayforce.py +2 -1
  6. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/paylocity.py +2 -1
  7. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/recruitee.py +1 -1
  8. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/LICENSE +0 -0
  9. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/README.md +0 -0
  10. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/__init__.py +0 -0
  11. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/__init__.py +0 -0
  12. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/ashby.py +0 -0
  13. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/breezy.py +0 -0
  14. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/greenhouse.py +0 -0
  15. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/hireology.py +0 -0
  16. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/jazzhr.py +0 -0
  17. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/lever.py +0 -0
  18. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/manatal.py +0 -0
  19. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/oracle.py +0 -0
  20. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/paycor.py +0 -0
  21. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/smartrecruiters.py +0 -0
  22. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/teamtailor.py +0 -0
  23. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/workable.py +0 -0
  24. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/adapters/wttj.py +0 -0
  25. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/cli.py +0 -0
  26. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/__init__.py +0 -0
  27. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/accounts.py +0 -0
  28. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/adapter.py +0 -0
  29. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/attempts.py +0 -0
  30. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/browser.py +0 -0
  31. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/commands.py +0 -0
  32. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/matching.py +0 -0
  33. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/paths.py +0 -0
  34. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/registry.py +0 -0
  35. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/core/results.py +0 -0
  36. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/py.typed +0 -0
  37. {atsfill-0.0.4.dev37 → atsfill-0.0.4.dev38}/src/atsfill/registry.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atsfill
3
- Version: 0.0.4.dev37
3
+ Version: 0.0.4.dev38
4
4
  Summary: Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle.
5
5
  Keywords: job-applications,ats,ashby,greenhouse,teamtailor,ai-agents,cli
6
6
  Author: shbernal
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.4.dev37"
3
+ version = "0.0.4.dev38"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -68,7 +68,7 @@ select = [
68
68
  [tool.pytest.ini_options]
69
69
  testpaths = ["tests"]
70
70
  markers = ["live: drives a real hiring system page with data from .env and .tmp/; opt-in with -m live"]
71
- addopts = "-m 'not live' -n 8"
71
+ addopts = "-m 'not live' -n 8 --dist loadscope"
72
72
 
73
73
  [[tool.uv.index]]
74
74
  name = "testpypi"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.4.dev37"
3
+ version = "0.0.4.dev38"
4
4
  description = "Read, dry-run and submit job application forms on hiring systems: Ashby, Greenhouse, Teamtailor, Welcome to the Jungle."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -55,7 +55,7 @@ testpaths = ["tests"]
55
55
  markers = [
56
56
  "live: drives a real hiring system page with data from .env and .tmp/; opt-in with -m live",
57
57
  ]
58
- addopts = "-m 'not live' -n 8"
58
+ addopts = "-m 'not live' -n 8 --dist loadscope"
59
59
 
60
60
  [[tool.uv.index]]
61
61
  name = "testpypi"
@@ -30,6 +30,7 @@ CHALLENGE = "iframe[src*='recaptcha/api2/bframe']"
30
30
  FORM_TIMEOUT_MS = 30_000
31
31
  UPLOAD_TIMEOUT_MS = 30_000
32
32
  SHOWN_TIMEOUT_MS = 2_000
33
+ STATES_TIMEOUT_MS = 15_000 # for the state's list a country change refetches
33
34
  SETTLE_MS = 300 # for React to render what a response brought
34
35
  CAPTCHA_TIMEOUT_MS = 20_000
35
36
  SUBMIT_TIMEOUT_MS = 90_000
@@ -215,12 +216,14 @@ class BambooHR:
215
216
  case "file":
216
217
  _attach(form, str(name), answer)
217
218
  case "select" if field_id == "countryId":
219
+ if _shown(control) == value:
220
+ continue # the state's list stays
218
221
  with (
219
222
  suppress(Timeout),
220
223
  page.expect_response(
221
- lambda r: "/ajax/get_states" in r.url, timeout=SHOWN_TIMEOUT_MS
224
+ lambda r: "/ajax/get_states" in r.url, timeout=STATES_TIMEOUT_MS
222
225
  ),
223
- ): # the state's list follows the country, none when it stays
226
+ ): # the state's list follows the country
224
227
  _pick(page, control, value)
225
228
  page.wait_for_timeout(SETTLE_MS)
226
229
  case "select":
@@ -35,6 +35,7 @@ STEP_TIMEOUT_MS = 20_000
35
35
  SUBMIT_TIMEOUT_MS = 90_000
36
36
  UPDATE_TRIES = 3
37
37
  FOLLOWUP_TIMEOUT_MS = 3_000
38
+ DIAL_TIMEOUT_MS = 2_000 # per dial code tried, longest first
38
39
  NEXT_TRIES = 3
39
40
  STEP_POLLS = 16 # of POLL_MS, before Next is clicked again
40
41
  POLL_MS = 500
@@ -769,7 +770,7 @@ def _fill_phone(page: Page, selector: str, value: str) -> None:
769
770
  dial.press_sequentially(f"+{code}", delay=10)
770
771
  options = page.locator(_option(dial)).filter(has_text=re.compile(rf"\+{code}(\s|$)"))
771
772
  with suppress(Timeout):
772
- options.first.wait_for(timeout=2_000)
773
+ options.first.wait_for(timeout=DIAL_TIMEOUT_MS)
773
774
  if options.count():
774
775
  main = options.filter(has_text=MAIN_COUNTRY.get(code, "\0"))
775
776
  (main if main.count() else options).first.click()
@@ -31,6 +31,7 @@ SUBMIT = "[data-automation-id=btnSubmit]"
31
31
  STEP = "#appDetailDiv .type-bold.float-right" # "Step 2 of 5"
32
32
  FORCED_RESUME = ".modal.in #btn-forceResume"
33
33
  FORM_TIMEOUT_MS = 30_000
34
+ COOKIE_TIMEOUT_MS = 5_000
34
35
  STEP_TIMEOUT_MS = 20_000
35
36
  UPLOAD_TIMEOUT_MS = 30_000
36
37
  SUBMIT_TIMEOUT_MS = 90_000
@@ -473,7 +474,7 @@ def _present(page: Page, control: Control) -> bool:
473
474
  def _dismiss_cookies(page: Page) -> None:
474
475
  close = page.locator("#onetrust-banner-sdk .onetrust-close-btn-handler")
475
476
  with suppress(Timeout):
476
- close.first.wait_for(state="visible", timeout=5_000)
477
+ close.first.wait_for(state="visible", timeout=COOKIE_TIMEOUT_MS)
477
478
  close.first.click()
478
479
 
479
480
 
@@ -63,7 +63,7 @@ _READ = """form => {
63
63
  field = {id: name, required: false, options: [], accept: null,
64
64
  maxLength: el.maxLength > 0 ? el.maxLength : null};
65
65
  if (el.type === "radio") field.kind = "radio";
66
- else if (el.type === "checkbox" && /\.(flag|consent)$/.test(name)) {
66
+ else if (el.type === "checkbox" && /\\.(flag|consent)$/.test(name)) {
67
67
  field.kind = "legal";
68
68
  field.label = text(form.querySelector(`[id="${el.getAttribute("aria-labelledby")}"]`));
69
69
  } else if (el.type === "checkbox") field.kind = "checkboxes";
File without changes
File without changes