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.
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/PKG-INFO +1 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/pyproject.toml +1 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/pyproject.toml.orig +1 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/eightfold.py +22 -9
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/ukg.py +0 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workatastartup.py +0 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workday.py +0 -1
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/LICENSE +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/README.md +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/__init__.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/__init__.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/adp.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/adpmyjobs.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/ashby.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/bamboohr.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/breezy.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/dayforce.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/greenhouse.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/gupy.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hireology.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hiringthing.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/hrmdirect.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/isolvedhire.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jazzhr.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jobaffinity.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/jobstreet.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/join.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/lever.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/manatal.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/oracle.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/paycor.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/paylocity.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/personio.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/phenom.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/pinpoint.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/recruitee.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/recruiterflow.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/rippling.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/smartrecruiters.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/successfactors.js +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/successfactors.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/taleo.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/teamtailor.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/welcomekit.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/wellfound.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/werecruit.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/workable.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/wttj.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/adapters/zohorecruit.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/cli.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/__init__.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/accounts.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/adapter.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/attempts.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/browser.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/commands.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/conditions.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/countries.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/html.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/matching.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/otp.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/passwords.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/paths.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/registry.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/results.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/snapshot.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/core/telemetry.py +0 -0
- {atsfill-0.0.8.dev225 → atsfill-0.0.8.dev227}/src/atsfill/py.typed +0 -0
- {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.
|
|
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
|
|
@@ -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
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|