atsfill 0.0.8.dev225__tar.gz → 0.0.8.dev227__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 (69) hide show
  1. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/PKG-INFO +1 -1
  2. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/pyproject.toml +1 -1
  3. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/pyproject.toml.orig +1 -1
  4. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/eightfold.py +22 -9
  5. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/ukg.py +0 -1
  6. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workatastartup.py +0 -1
  7. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workday.py +0 -1
  8. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/LICENSE +0 -0
  9. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/README.md +0 -0
  10. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/__init__.py +0 -0
  11. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/__init__.py +0 -0
  12. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/adp.py +0 -0
  13. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/adpmyjobs.py +0 -0
  14. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/ashby.py +0 -0
  15. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/bamboohr.py +0 -0
  16. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/breezy.py +0 -0
  17. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/dayforce.py +0 -0
  18. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/greenhouse.py +0 -0
  19. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/gupy.py +0 -0
  20. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hireology.py +0 -0
  21. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hiringthing.py +0 -0
  22. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hrmdirect.py +0 -0
  23. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/isolvedhire.py +0 -0
  24. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jazzhr.py +0 -0
  25. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jobaffinity.py +0 -0
  26. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jobstreet.py +0 -0
  27. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/join.py +0 -0
  28. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/lever.py +0 -0
  29. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/manatal.py +0 -0
  30. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/oracle.py +0 -0
  31. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/paycor.py +0 -0
  32. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/paylocity.py +0 -0
  33. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/personio.py +0 -0
  34. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/phenom.py +0 -0
  35. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/pinpoint.py +0 -0
  36. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/recruitee.py +0 -0
  37. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/recruiterflow.py +0 -0
  38. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/rippling.py +0 -0
  39. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/smartrecruiters.py +0 -0
  40. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/successfactors.js +0 -0
  41. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/successfactors.py +0 -0
  42. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/taleo.py +0 -0
  43. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/teamtailor.py +0 -0
  44. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/welcomekit.py +0 -0
  45. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/wellfound.py +0 -0
  46. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/werecruit.py +0 -0
  47. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workable.py +0 -0
  48. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/wttj.py +0 -0
  49. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/zohorecruit.py +0 -0
  50. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/cli.py +0 -0
  51. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/__init__.py +0 -0
  52. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/accounts.py +0 -0
  53. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/adapter.py +0 -0
  54. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/attempts.py +0 -0
  55. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/browser.py +0 -0
  56. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/commands.py +0 -0
  57. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/conditions.py +0 -0
  58. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/countries.py +0 -0
  59. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/html.py +0 -0
  60. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/matching.py +0 -0
  61. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/otp.py +0 -0
  62. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/passwords.py +0 -0
  63. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/paths.py +0 -0
  64. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/registry.py +0 -0
  65. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/results.py +0 -0
  66. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/snapshot.py +0 -0
  67. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/telemetry.py +0 -0
  68. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/py.typed +0 -0
  69. {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/registry.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atsfill
3
- Version: 0.0.8.dev225
3
+ Version: 0.0.8.dev227
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.8.dev225"
3
+ version = "0.0.8.dev227"
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"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "atsfill"
3
- version = "0.0.8.dev225"
3
+ version = "0.0.8.dev227"
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"
@@ -37,6 +37,8 @@ FORM_TIMEOUT_MS = 30_000
37
37
  SHOWN_TIMEOUT_MS = 2_000
38
38
  OPTIONS_TIMEOUT_MS = 5_000
39
39
  FOCUS_TIMEOUT_MS = 500
40
+ LIST_CLOSE_TIMEOUT_MS = 2_000 # a list can close late on a page still loading
41
+ PICK_CLICKS = 3 # the list can lose a click on its option
40
42
  UPLOAD_TIMEOUT_MS = 30_000
41
43
  SUBMIT_TIMEOUT_MS = 90_000
42
44
  PARSE_SETTLE_MS = 2_000
@@ -485,16 +487,27 @@ def _pick(page: Page, combo, value: str, exact: bool) -> None:
485
487
 
486
488
  def _choose(page: Page, combo, option) -> None:
487
489
  """Clicks a combobox's option and waits for its list to close and the combobox to take the
488
- focus back: typed before that, the next answer lands in the combobox."""
490
+ focus back: typed before that, the next answer lands in the combobox. A list still open over
491
+ an unchanged combobox lost the click, so the option is clicked again; clicked once it took,
492
+ it would clear. A list that stays open is dismissed, as it lies over the next control, for
493
+ the read-back to catch what the combobox holds."""
489
494
  listbox = page.locator(f"[id={json.dumps(combo.get_attribute('aria-controls'))}]")
490
- option.click()
491
- with suppress(Timeout):
492
- listbox.wait_for(state="hidden", timeout=FOCUS_TIMEOUT_MS)
493
- page.wait_for_function(
494
- "el => document.activeElement === el",
495
- arg=combo.element_handle(),
496
- timeout=FOCUS_TIMEOUT_MS,
497
- )
495
+ held = combo.input_value()
496
+ for _ in range(PICK_CLICKS):
497
+ with suppress(Timeout):
498
+ option.click(timeout=LIST_CLOSE_TIMEOUT_MS)
499
+ listbox.wait_for(state="hidden", timeout=LIST_CLOSE_TIMEOUT_MS)
500
+ if listbox.is_hidden():
501
+ with suppress(Timeout):
502
+ page.wait_for_function(
503
+ "el => document.activeElement === el",
504
+ arg=combo.element_handle(),
505
+ timeout=FOCUS_TIMEOUT_MS,
506
+ )
507
+ return
508
+ if combo.input_value() != held:
509
+ break
510
+ combo.press("Escape")
498
511
 
499
512
 
500
513
  def _phone(page: Page, box, value: str) -> None:
@@ -33,7 +33,6 @@ UPLOAD_TIMEOUT_MS = 30_000
33
33
  SUBMIT_TIMEOUT_MS = 90_000
34
34
  SETTLE_MS = 500
35
35
  YES_NO = ["Yes", "No"]
36
- DATE_SHOWN = re.compile(r"(\d\d)/(\d\d)/(\d{4})")
37
36
  COUNTRY, STATE = "Country", "State"
38
37
  DECLINE_BOX = "input[type=checkbox][data-automation$='-decline-checkbox']"
39
38
  DAYS, DOCUMENTS = "availability_days", "documents"
@@ -437,7 +437,6 @@ def _in_entry(form: Locator, entry: str | None, node: str) -> Locator:
437
437
  ENGINEERING = Is("role", ["Engineering"])
438
438
  A_ROLE = Is("role") # shown once a role is picked
439
439
  YES_NO = ["Yes", "No"]
440
- SIZES = ["Not Interested", "OK", "Preferred"]
441
440
  T, C, M, TA = FieldType.TEXT, FieldType.CHOICE, FieldType.MULTI_CHOICE, FieldType.TYPEAHEAD
442
441
  STEPS: dict[str, list[Control]] = {
443
442
  "personal": [
@@ -112,7 +112,6 @@ ENTRY_LISTS: list[EntryList] = [
112
112
  ("lastYearAttended", "To (Actual or Expected)", "year", "To (Actual or Expected)"),
113
113
  ]),
114
114
  ] # fmt: skip
115
- SCHOOL_SEARCH = "university" # finds schools where the tenant lists them
116
115
  # The school: a search prompt where the tenant lists schools, else a text input; one field
117
116
  SCHOOL_IDS = {"education--schoolName": "education--school"}
118
117
  BRACKETED = re.compile(r"\(([^()]+)\)")
File without changes
File without changes