atsfill 0.0.4.dev67__tar.gz → 0.0.4.dev68__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 (38) hide show
  1. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/PKG-INFO +1 -1
  2. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/pyproject.toml +1 -1
  3. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/pyproject.toml.orig +1 -1
  4. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/workable.py +9 -5
  5. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/LICENSE +0 -0
  6. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/README.md +0 -0
  7. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/__init__.py +0 -0
  8. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/__init__.py +0 -0
  9. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/ashby.py +0 -0
  10. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/bamboohr.py +0 -0
  11. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/breezy.py +0 -0
  12. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/dayforce.py +0 -0
  13. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/greenhouse.py +0 -0
  14. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/hireology.py +0 -0
  15. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/jazzhr.py +0 -0
  16. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/lever.py +0 -0
  17. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/manatal.py +0 -0
  18. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/oracle.py +0 -0
  19. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/paycor.py +0 -0
  20. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/paylocity.py +0 -0
  21. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/phenom.py +0 -0
  22. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/recruitee.py +0 -0
  23. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/smartrecruiters.py +0 -0
  24. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/teamtailor.py +0 -0
  25. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/adapters/wttj.py +0 -0
  26. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/cli.py +0 -0
  27. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/__init__.py +0 -0
  28. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/accounts.py +0 -0
  29. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/adapter.py +0 -0
  30. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/attempts.py +0 -0
  31. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/browser.py +0 -0
  32. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/commands.py +0 -0
  33. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/matching.py +0 -0
  34. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/paths.py +0 -0
  35. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/registry.py +0 -0
  36. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/core/results.py +0 -0
  37. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/src/atsfill/py.typed +0 -0
  38. {atsfill-0.0.4.dev67 → atsfill-0.0.4.dev68}/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.dev67
3
+ Version: 0.0.4.dev68
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.dev67"
3
+ version = "0.0.4.dev68"
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.4.dev67"
3
+ version = "0.0.4.dev68"
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"
@@ -25,6 +25,7 @@ API = "https://apply.workable.com/api/v1/jobs/{code}/form"
25
25
  APPLIED = re.compile(r"/api/v1/jobs/[0-9A-F]{10}/apply$")
26
26
  FORM = "form[data-ui=application-form]"
27
27
  COOKIES = "[data-ui=cookie-consent-decline]"
28
+ UPLOADED = "[data-action=delete]" # an uploading file shows its name and an abort button
28
29
  FORM_TIMEOUT_MS = 30_000
29
30
  COOKIE_TIMEOUT_MS = 5_000
30
31
  OPTIONS_TIMEOUT_MS = 5_000
@@ -101,7 +102,7 @@ _READ = """form => {
101
102
  return found;
102
103
  }"""
103
104
 
104
- # What each field shows: a choice its checked option's label, a file its attached name (a photo
105
+ # What each field shows: a choice its checked option's label, a file its uploaded name (a photo
105
106
  # its preview's alt), the phone its country's dial code then its number.
106
107
  _READ_BACK = """(form, kinds) => {
107
108
  const text = el => el ? el.textContent.replace(/\\s+/g, " ").trim() : null;
@@ -114,7 +115,9 @@ _READ_BACK = """(form, kinds) => {
114
115
  if (kind === "file") {
115
116
  const zone = el.closest("[data-role=dropzone]");
116
117
  const preview = zone?.querySelector("[data-role=preview] img"); // a photo, named by its alt
117
- out[id] = preview ? preview.alt : text(zone?.querySelector("[data-id=filename]"));
118
+ const uploaded = zone?.querySelector("[data-action=delete]"); // not while it uploads
119
+ out[id] = !uploaded ? null
120
+ : preview ? preview.alt : text(zone.querySelector("[data-id=filename]"));
118
121
  } else if (kind === "phone") {
119
122
  const dial = (el.querySelector("button[aria-label]")?.getAttribute("aria-label") || "")
120
123
  .match(/\\((\\+\\d+)\\)/);
@@ -201,13 +204,14 @@ class Workable:
201
204
  field.set_input_files(values[0])
202
205
  zone = field.locator("xpath=ancestor::*[@data-role='dropzone']")
203
206
  crop = page.locator("button[data-ui=crop-image]")
207
+ # attaching another file while one uploads empties it, so each waits
208
+ uploaded = zone.locator(UPLOADED)
204
209
  with suppress(Timeout):
205
- zone.locator("[data-id=filename]").or_(crop).first.wait_for(
206
- timeout=UPLOAD_TIMEOUT_MS
207
- )
210
+ uploaded.or_(crop).first.wait_for(timeout=UPLOAD_TIMEOUT_MS)
208
211
  if crop.is_visible():
209
212
  crop.click()
210
213
  crop.wait_for(state="hidden", timeout=UPLOAD_TIMEOUT_MS)
214
+ uploaded.wait_for(timeout=UPLOAD_TIMEOUT_MS)
211
215
  case "phone": # the number's dial code picks the country
212
216
  number = field.locator("input[type=tel]")
213
217
  number.fill("")
File without changes
File without changes