atsfill 0.0.4.dev127__tar.gz → 0.0.4.dev129__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.dev127 → atsfill-0.0.4.dev129}/PKG-INFO +1 -1
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/pyproject.toml +1 -1
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/pyproject.toml.orig +1 -1
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/hrmdirect.py +9 -6
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/successfactors.py +36 -2
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/ukg.py +19 -13
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/commands.py +1 -1
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/registry.toml +5 -5
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/LICENSE +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/README.md +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/__init__.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/__init__.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/ashby.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/bamboohr.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/breezy.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/dayforce.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/eightfold.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/greenhouse.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/gupy.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/hireology.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/hiringthing.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/jazzhr.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/join.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/lever.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/manatal.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/oracle.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/paycor.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/paylocity.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/personio.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/phenom.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/pinpoint.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/recruitee.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/rippling.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/smartrecruiters.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/successfactors.js +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/taleo.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/teamtailor.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/workable.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/workday.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/wttj.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/adapters/zohorecruit.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/cli.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/__init__.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/accounts.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/adapter.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/attempts.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/browser.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/conditions.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/html.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/matching.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/passwords.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/paths.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/registry.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/core/results.py +0 -0
- {atsfill-0.0.4.dev127 → atsfill-0.0.4.dev129}/src/atsfill/py.typed +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.dev129
|
|
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
|
|
@@ -97,7 +97,7 @@ class HRMDirect:
|
|
|
97
97
|
name = "hrmdirect"
|
|
98
98
|
per_employer = True
|
|
99
99
|
asks = {"name"}
|
|
100
|
-
known_gaps = {"screening_first": Gap.FLOW
|
|
100
|
+
known_gaps = {"screening_first": Gap.FLOW}
|
|
101
101
|
side_effects = [
|
|
102
102
|
SideEffect(
|
|
103
103
|
"sign_up", "employer", "the account is the employer's candidate, emailed a link"
|
|
@@ -184,17 +184,18 @@ class HRMDirect:
|
|
|
184
184
|
|
|
185
185
|
def sign_up(self, page: Page, email: str, password: str, details: SignUpDetails) -> None:
|
|
186
186
|
"""Fills the apply page's first step, which creates the account signed in and sets no
|
|
187
|
-
password: the email that follows holds a link to set one, `blocked: email_link`.
|
|
187
|
+
password: the email that follows holds a link to set one, `blocked: email_link`. The
|
|
188
|
+
mobile phone is given only where the org requires it; a missing one is refused before
|
|
189
|
+
anything is sent."""
|
|
188
190
|
_to_apply(page)
|
|
189
191
|
if not page.locator(IDENTITY).is_visible():
|
|
190
192
|
raise Unsupported(
|
|
191
193
|
known_gap(self, "screening_first", "the form's first page comes before sign-up")
|
|
192
194
|
)
|
|
193
195
|
phone = page.locator(f"{IDENTITY} .form-group:has(input.mobile-number)")
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
)
|
|
196
|
+
phone_asked = phone.count() and not phone.locator(".common-option-label").count()
|
|
197
|
+
if phone_asked and not details.phone:
|
|
198
|
+
raise Refused("sign_up_details: no phone")
|
|
198
199
|
if page.locator(RECAPTCHA).count():
|
|
199
200
|
raise Blocked("captcha: a reCAPTCHA box keeps the sign-up's Continue disabled")
|
|
200
201
|
first, _, last = (details.name or "").strip().partition(" ")
|
|
@@ -203,6 +204,8 @@ class HRMDirect:
|
|
|
203
204
|
form.locator("input.last-name").fill(last or first)
|
|
204
205
|
form.locator("input.email").fill(email)
|
|
205
206
|
form.locator("input.email-confirm").fill(email)
|
|
207
|
+
if phone_asked:
|
|
208
|
+
form.locator("input.mobile-number").fill(details.phone or "")
|
|
206
209
|
for group in form.locator(".radio-group:has(input[required])").all():
|
|
207
210
|
group.locator("label:has(input[value=false])").click() # declines, the least given
|
|
208
211
|
form.locator("button.submit-button").click()
|
|
@@ -34,6 +34,8 @@ SIGNED_IN = re.compile(r"\bsignOut|\blogout\b|_logout", re.IGNORECASE)
|
|
|
34
34
|
FIELDS = (Path(__file__).with_suffix(".js")).read_text()
|
|
35
35
|
# What the candidate pages show once loaded
|
|
36
36
|
SIGN_IN = "#username"
|
|
37
|
+
COUNTRY = "fbclc_country" # its options' values are ISO 3166 alpha-2 codes
|
|
38
|
+
PHONE, CALLING_CODE = "#fbclc_phoneNumber", "#fbclc_ituCode" # `CA`: `Canada (+1)`
|
|
37
39
|
SIGN_UP = "#fbclc_userName"
|
|
38
40
|
QUICK_APPLY = "#fbqa_apply"
|
|
39
41
|
FORM = ".RCMFormField"
|
|
@@ -86,6 +88,22 @@ def _company(request: Request) -> list[tuple[str, str]]:
|
|
|
86
88
|
)
|
|
87
89
|
|
|
88
90
|
|
|
91
|
+
def _calling_code(select: Locator, details: SignUpDetails) -> tuple[str, str]:
|
|
92
|
+
"""The calling code's option for the E.164 phone, the one of `country` among the countries
|
|
93
|
+
sharing it, and the national number that follows the code."""
|
|
94
|
+
options = select.evaluate("s => [...s.options].map(o => [o.value, o.textContent])")
|
|
95
|
+
phone = (details.phone or "").removeprefix("+")
|
|
96
|
+
codes = [
|
|
97
|
+
(len(m[1]), value == details.country, value)
|
|
98
|
+
for value, text in options
|
|
99
|
+
if (m := re.search(r"\(\+(\d+)\)", text)) and phone.startswith(m[1])
|
|
100
|
+
]
|
|
101
|
+
if not codes:
|
|
102
|
+
raise Unsupported(f"unhandled_rendering: the sign-up offers no calling code for {phone}")
|
|
103
|
+
length, _, value = max(codes, key=lambda c: c[:2]) # the first of the best
|
|
104
|
+
return value, phone[length:]
|
|
105
|
+
|
|
106
|
+
|
|
89
107
|
class SuccessFactors:
|
|
90
108
|
name = "successfactors"
|
|
91
109
|
per_employer = True
|
|
@@ -146,6 +164,10 @@ class SuccessFactors:
|
|
|
146
164
|
raise Refused(f"wrong_password: {message}") from None
|
|
147
165
|
|
|
148
166
|
def sign_up(self, page: Page, email: str, password: str, details: SignUpDetails) -> None:
|
|
167
|
+
"""Creates the account from the career site's sign-up: the name, the country of
|
|
168
|
+
residence from `country` (the list's first without it), and the phone where the site
|
|
169
|
+
requires one, its calling code picked from the number; a missing phone is refused
|
|
170
|
+
before anything is sent."""
|
|
149
171
|
self._candidate(page)
|
|
150
172
|
if page.locator(SIGN_IN).count():
|
|
151
173
|
page.locator(REGISTER).first.click()
|
|
@@ -160,6 +182,9 @@ class SuccessFactors:
|
|
|
160
182
|
) from None
|
|
161
183
|
register.first.click()
|
|
162
184
|
page.locator(SIGN_UP).wait_for(timeout=LANDING_TIMEOUT_MS)
|
|
185
|
+
phone_asked = page.locator(f"{PHONE}[aria-required=true]:visible").count() > 0
|
|
186
|
+
if phone_asked and not details.phone:
|
|
187
|
+
raise Refused("sign_up_details: no phone")
|
|
163
188
|
first, _, last = (details.name or "").strip().partition(" ")
|
|
164
189
|
for selector, value in [
|
|
165
190
|
(SIGN_UP, email),
|
|
@@ -170,10 +195,17 @@ class SuccessFactors:
|
|
|
170
195
|
("#fbclc_lName", last or first),
|
|
171
196
|
]:
|
|
172
197
|
page.fill(selector, value)
|
|
173
|
-
|
|
198
|
+
if phone_asked and details.phone:
|
|
199
|
+
code, national = _calling_code(page.locator(CALLING_CODE), details)
|
|
200
|
+
page.locator(CALLING_CODE).select_option(code)
|
|
201
|
+
page.fill(PHONE, national)
|
|
202
|
+
for select in page.locator("select:visible").all(): # the country, any other
|
|
174
203
|
if not select.input_value():
|
|
175
204
|
values = select.evaluate("s => [...s.options].map(o => o.value).filter(v => v)")
|
|
176
|
-
select.
|
|
205
|
+
wanted = details.country if select.get_attribute("id") == COUNTRY else None
|
|
206
|
+
if wanted and wanted not in values:
|
|
207
|
+
raise Unsupported(f"unhandled_rendering: the sign-up's countries lack {wanted}")
|
|
208
|
+
select.select_option(wanted or values[0])
|
|
177
209
|
if page.locator(PRIVACY).count():
|
|
178
210
|
page.locator(PRIVACY).click()
|
|
179
211
|
dialog = page.locator("[role=dialog]:visible").last
|
|
@@ -201,6 +233,8 @@ class SuccessFactors:
|
|
|
201
233
|
if page.locator(f"{SIGN_IN}:visible").count(): # created, signed out
|
|
202
234
|
self.sign_in(page, email, password)
|
|
203
235
|
return
|
|
236
|
+
if self.signed_in(page.request, None): # created, back on the career site
|
|
237
|
+
return
|
|
204
238
|
raise Unsupported(f"unhandled_rendering: the sign-up led to {urlsplit(page.url).path}")
|
|
205
239
|
|
|
206
240
|
def browser_read(self, page: Page) -> list[Field]:
|
|
@@ -36,7 +36,6 @@ YES_NO = ["Yes", "No"]
|
|
|
36
36
|
DATE_SHOWN = re.compile(r"(\d\d)/(\d\d)/(\d{4})")
|
|
37
37
|
COUNTRY, STATE = "Country", "State"
|
|
38
38
|
DAYS, DOCUMENTS = "availability_days", "documents"
|
|
39
|
-
PHONE_GAP = "sign_up_phone"
|
|
40
39
|
|
|
41
40
|
# Auth0's error codes on the sign-in and sign-up pages, by what atsfill raises
|
|
42
41
|
ERRORS = [
|
|
@@ -218,8 +217,8 @@ def board(url: str) -> Board | None:
|
|
|
218
217
|
class UKG:
|
|
219
218
|
name = "ukg"
|
|
220
219
|
per_employer = True
|
|
221
|
-
asks = {"name"}
|
|
222
|
-
known_gaps = {
|
|
220
|
+
asks = {"name", "phone"} # the phone only some tenants require, asked before the sign-up
|
|
221
|
+
known_gaps: dict[str, Gap] = {}
|
|
223
222
|
side_effects = [
|
|
224
223
|
SideEffect("sign_up", "employer", "the account is created in the employer's tenant"),
|
|
225
224
|
SideEffect("upload", "hiring_system", "a document is stored in the account's documents"),
|
|
@@ -284,7 +283,7 @@ class UKG:
|
|
|
284
283
|
_left_sign_in(page)
|
|
285
284
|
if "/AuthCode/Register" not in page.url:
|
|
286
285
|
return
|
|
287
|
-
_register(page, details
|
|
286
|
+
_register(page, details)
|
|
288
287
|
|
|
289
288
|
def browser_read(self, page: Page) -> list[Field]:
|
|
290
289
|
found = board(page.url)
|
|
@@ -397,26 +396,33 @@ def _left_sign_in(page: Page) -> None:
|
|
|
397
396
|
raise Unsupported("unhandled_rendering: the sign-in page answered nothing")
|
|
398
397
|
|
|
399
398
|
|
|
400
|
-
def _register(page: Page,
|
|
401
|
-
"""The tenant's own step after the sign-up: the name,
|
|
402
|
-
|
|
399
|
+
def _register(page: Page, details: SignUpDetails) -> None:
|
|
400
|
+
"""The tenant's own step after the sign-up: the name, the phone where the tenant requires
|
|
401
|
+
it, and the privacy policy's box on some tenants; the optional consents (text messages, AI
|
|
402
|
+
scoring, ticked by default) are declined. Its inputs take typed keys only: a filled value
|
|
403
403
|
leaves Create account disabled."""
|
|
404
404
|
page.locator("input[name=firstName]").wait_for(timeout=FORM_TIMEOUT_MS)
|
|
405
405
|
page.wait_for_load_state("networkidle")
|
|
406
|
+
first, _, last = (details.name or "").strip().partition(" ")
|
|
407
|
+
values = [("firstName", first), ("lastName", last or first)]
|
|
406
408
|
if page.locator("ukg-input[name=phoneNumber][required=true]").count():
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
for field, value in (("firstName", first), ("lastName", last or first)):
|
|
409
|
+
values.append(("phoneNumber", details.phone or ""))
|
|
410
|
+
for field, value in values:
|
|
410
411
|
page.locator(f"input[name={field}]").click()
|
|
411
412
|
page.locator(f"input[name={field}]").press_sequentially(value)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
if box
|
|
413
|
+
for box in page.locator("ukg-checkbox[data-automation*=-checkbox]:visible").all():
|
|
414
|
+
wanted = "privacy" in (box.get_attribute("data-automation") or "")
|
|
415
|
+
if _ticked(box) != wanted:
|
|
415
416
|
box.click()
|
|
416
417
|
page.get_by_role("button", name="Create account").click()
|
|
417
418
|
page.wait_for_url(lambda u: "/AuthCode/Register" not in u, timeout=FORM_TIMEOUT_MS)
|
|
418
419
|
|
|
419
420
|
|
|
421
|
+
def _ticked(box: Locator) -> bool:
|
|
422
|
+
"""A `ukg-checkbox`'s state: `aria-checked` once clicked, `checked` as the page set it."""
|
|
423
|
+
return "true" in (box.get_attribute("aria-checked"), box.get_attribute("checked"))
|
|
424
|
+
|
|
425
|
+
|
|
420
426
|
def _field(raw: dict[str, Any], states: dict[str, list[str]] | None) -> Field:
|
|
421
427
|
kind, field_id = raw["kind"], raw["id"]
|
|
422
428
|
label = raw["label"] or field_id
|
|
@@ -63,7 +63,7 @@ def _login_required(url: str, adapter: NeedsAccount, user: str) -> Result:
|
|
|
63
63
|
|
|
64
64
|
type Credentials = tuple[str, str] # email, password
|
|
65
65
|
# Refusals the page states before any account exists: the generated password goes.
|
|
66
|
-
NO_ACCOUNT = {"email_in_use", "email_domain_rejected", "password_rule"}
|
|
66
|
+
NO_ACCOUNT = {"email_in_use", "email_domain_rejected", "password_rule", "sign_up_details"}
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
def _email_link(reason: str | None, email: str, command: str) -> str | None:
|
|
@@ -96,7 +96,7 @@ share = 0.0350
|
|
|
96
96
|
account = "to_read"
|
|
97
97
|
hosting = ["hosted"]
|
|
98
98
|
adapter = "successfactors"
|
|
99
|
-
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "0d8baea", by = "agent", reason = "quick_apply_sign_up: a Quick Apply page creates the account and sends the application in one submit, its sign-in offering no sign-up; sign_up_fields: a sign-up asking
|
|
99
|
+
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "0d8baea", by = "agent", reason = "quick_apply_sign_up: a Quick Apply page creates the account and sends the application in one submit, its sign-in offering no sign-up; sign_up_fields: a sign-up asking who may see the profile" }
|
|
100
100
|
mapped = { date = 2026-10-20, version = "0.0.2", by = "agent", commit = "7934b25" }
|
|
101
101
|
|
|
102
102
|
[ukg]
|
|
@@ -106,7 +106,7 @@ account = "to_read"
|
|
|
106
106
|
hosting = ["hosted"]
|
|
107
107
|
adapter = "ukg"
|
|
108
108
|
mapped = { date = 2026-10-20, version = "0.0.2", by = "agent", commit = "7934b25" }
|
|
109
|
-
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "a60a17d", by = "agent", reason = "
|
|
109
|
+
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "a60a17d", by = "agent", reason = "unhandled on the forms the sign-up now reaches, 3 of 8 tenants ready: no gender decline box to tick (3), a State whose condition names no Country (1), a numeric answer read back differently (1)" }
|
|
110
110
|
|
|
111
111
|
[paycom]
|
|
112
112
|
kind = "ats"
|
|
@@ -260,10 +260,10 @@ dry_run_verified = { date = 2026-10-22, version = "0.0.3", by = "adapter_gate",
|
|
|
260
260
|
[ukgready]
|
|
261
261
|
kind = "ats"
|
|
262
262
|
share = 0.0085
|
|
263
|
-
account = "to_read" # the
|
|
263
|
+
account = "to_read" # the sign-in's Create a new account sets a password, asking the name, country and zip code
|
|
264
264
|
hosting = ["hosted"]
|
|
265
265
|
mapped = { date = 2026-10-20, version = "0.0.2", by = "agent", commit = "7934b25" }
|
|
266
|
-
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "
|
|
266
|
+
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "b0cb322", by = "agent", reason = "unsupported_flow: profile_wizard: signed in, the form is the applicant portal's profile wizard, items of a dozen types edited in cards, entry lists, a security question and an electronic signature; not built within the round (1 tenant walked)" }
|
|
267
267
|
|
|
268
268
|
[adpmyjobs]
|
|
269
269
|
kind = "ats"
|
|
@@ -306,7 +306,7 @@ share = 0.0059
|
|
|
306
306
|
account = "to_read"
|
|
307
307
|
hosting = ["hosted"]
|
|
308
308
|
mapped = { date = 2026-10-20, version = "0.0.2", by = "agent", commit = "7934b25" }
|
|
309
|
-
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "211fe03", by = "agent", reason = "unsupported_flow: screening_first: the form's first page comes before the sign-up step (4 of 14 orgs);
|
|
309
|
+
unsupported = { date = 2026-10-26, version = "0.0.3", commit = "211fe03", by = "agent", reason = "unsupported_flow: screening_first: the form's first page comes before the sign-up step (4 of 14 orgs); a reCAPTCHA box on the sign-up step (1 of 17); 3 orgs signed in, under the 5 dry runs the gate needs" }
|
|
310
310
|
|
|
311
311
|
[applicantpro]
|
|
312
312
|
kind = "ats"
|
|
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
|