atsfill 0.0.4.dev100__tar.gz → 0.0.4.dev102__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.4.dev100 → atsfill-0.0.4.dev102}/PKG-INFO +1 -1
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/pyproject.toml +1 -1
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/pyproject.toml.orig +1 -1
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/smartrecruiters.py +20 -2
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/LICENSE +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/README.md +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/__init__.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/__init__.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/ashby.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/bamboohr.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/breezy.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/dayforce.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/eightfold.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/greenhouse.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/hireology.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/hiringthing.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/jazzhr.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/lever.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/manatal.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/oracle.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/paycor.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/paylocity.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/personio.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/phenom.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/pinpoint.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/recruitee.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/rippling.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/teamtailor.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/workable.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/workday.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/wttj.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/adapters/zohorecruit.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/cli.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/__init__.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/accounts.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/adapter.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/attempts.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/browser.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/commands.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/conditions.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/matching.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/passwords.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/paths.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/registry.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/core/results.py +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/src/atsfill/py.typed +0 -0
- {atsfill-0.0.4.dev100 → atsfill-0.0.4.dev102}/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.
|
|
3
|
+
Version: 0.0.4.dev102
|
|
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
|
|
@@ -35,6 +35,7 @@ KEY_DELAY_MS = 20
|
|
|
35
35
|
LOCATION_KEY_DELAY_MS = 30
|
|
36
36
|
NEXT_TRIES = 3
|
|
37
37
|
YES_NO = ["Yes", "No"]
|
|
38
|
+
NUMBER = re.compile(r"-?\d+([.,]\d+)?") # what an `input[type=number]` takes
|
|
38
39
|
|
|
39
40
|
# The profile page: (field id, the input, the element carrying `label` and `required`).
|
|
40
41
|
PROFILE = [
|
|
@@ -221,6 +222,8 @@ class SmartRecruiters:
|
|
|
221
222
|
if kind in SKIPPED:
|
|
222
223
|
return []
|
|
223
224
|
label = _plain(question["label"])
|
|
225
|
+
if kind == "currency": # an `input[type=number]`, its currency beside
|
|
226
|
+
label += " (a number)"
|
|
224
227
|
shown_when = self._shown_when(question["id"])
|
|
225
228
|
required = bool(question["required"])
|
|
226
229
|
unfillable = None
|
|
@@ -426,6 +429,14 @@ def _inputs(box: Locator, entry: dict[str, Any], question: dict[str, Any]) -> Lo
|
|
|
426
429
|
return box.locator("input:not([type=checkbox]), textarea").nth(n)
|
|
427
430
|
|
|
428
431
|
|
|
432
|
+
def _select(box: Locator, entry: dict[str, Any], question: dict[str, Any]) -> Locator:
|
|
433
|
+
"""The autocomplete of one of the question's selects, which holds its own options: the
|
|
434
|
+
selects of a group (work shifts, an EEO pair) share option ids."""
|
|
435
|
+
selects = [e["id"] for e in question["fields"] if e["type"] == "select"]
|
|
436
|
+
hosts = box.locator("spl-autocomplete, spl-multiselect-autocomplete")
|
|
437
|
+
return hosts.nth(selects.index(entry["id"]))
|
|
438
|
+
|
|
439
|
+
|
|
429
440
|
def _fill_question(
|
|
430
441
|
box: Locator, question: dict[str, Any], entry: dict[str, Any], answer: Answer
|
|
431
442
|
) -> None:
|
|
@@ -445,7 +456,11 @@ def _fill_question(
|
|
|
445
456
|
continue
|
|
446
457
|
target.click()
|
|
447
458
|
target.press_sequentially(value[:20], delay=KEY_DELAY_MS)
|
|
448
|
-
option =
|
|
459
|
+
option = (
|
|
460
|
+
_select(box, entry, question)
|
|
461
|
+
.locator(f"spl-select-option[value='{option_id}']")
|
|
462
|
+
.first
|
|
463
|
+
)
|
|
449
464
|
try:
|
|
450
465
|
option.wait_for(timeout=OPTION_TIMEOUT_MS)
|
|
451
466
|
except Timeout:
|
|
@@ -453,7 +468,10 @@ def _fill_question(
|
|
|
453
468
|
continue
|
|
454
469
|
option.click()
|
|
455
470
|
case _:
|
|
456
|
-
_inputs(box, entry, question)
|
|
471
|
+
target = _inputs(box, entry, question)
|
|
472
|
+
if target.get_attribute("type") == "number" and not NUMBER.fullmatch(values[0]):
|
|
473
|
+
return # a number input holds no text: it reads back empty
|
|
474
|
+
target.fill(values[0])
|
|
457
475
|
|
|
458
476
|
|
|
459
477
|
def _read_question(box: Locator, question: dict[str, Any], entry: dict[str, Any]) -> Answer | None:
|
|
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
|