SatelliteHR e2e — issues found

15 Oct 2026, 00:14 IST · qa.satellitehr.com · Attendance & Leave + Feedback tracker · full test report · BUGS.md · bugs.json

2 new failures · 0 regressions · 11 open issues · 7 sheet gaps · 0 no longer reproduce · 2 working

90 tests: 65 passed · 23 failed · 2 skipped · run failed

IssueDescriptionModuleSubmoduleStatusExpected resultActual resultTotal test coverage
NewNo logged issue: web clock-in and clock-out record the day against the shift (rows 1–3)AttendanceClock in / outNew failure — triageweb clock-in and clock-out record the day against the shift (rows 1–3)
expect(locator).toBeVisible() failed Locator: getByRole('dialog').filter({ hasText: /Clocking in at/ }).last().getByText(/Today:/) Expected: visible Timeout: 30000ms Error: element(s) not found
full error

web clock-in and clock-out record the day against the shift (rows 1–3)

Error: expect(locator).toBeVisible() failed

Locator: getByRole('dialog').filter({ hasText: /Clocking in at/ }).last().getByText(/Today:/)
Expected: visible
Timeout: 30000ms
Error: element(s) not found

Call log:
  - Expect "toBeVisible" getByRole('dialog').filter({ hasText: /Clocking in at/ }).last().getByText(/Today:/) with timeout 30000ms
  - waiting for getByRole('dialog').filter({ hasText: /Clocking in at/ }).last().getByText(/Today:/)
    - found getByRole('dialog').filter({ hasText: 'Start today\'s clock' }), intercepting action to run the handler
    - locator handler has finished, waiting for getByRole('dialog').filter({ hasText: 'Start today\'s clock' }) to be hidden
    - interception handler has finished, continuing
1 test: 1 fail
tests
  • ✗ web clock-in and clock-out record the day against the shift (rows 1–3) tests/journeys/al01-al02-attendance.spec.ts:15
NewNo logged issue: policy set matches the reviewed baselineLeavePoliciesNew failure — triagepolicy set matches the reviewed baseline
expect(string).toMatchSnapshot(expected) failed @@ -144,11 +144,11 @@ "name": "Paid Time Off — handbook 16.1", "accrual": { "rate": 1.25, "frequency": "monthly", "proration": true, + "startNextMonth": true }, "carryForward": {
full error

policy set matches the reviewed baseline

Error: expect(string).toMatchSnapshot(expected) failed

  @@ -144,11 +144,11 @@
       "name": "Paid Time Off — handbook 16.1",
       "accrual": {
         "rate": 1.25,
         "frequency": "monthly",
         "proration": true,
  -      "waitingDays": 30
  +      "startNextMonth": true
       },
       "carryForward": {
         "maxDays": 30
       },
1 test: 1 fail
tests
  • ✗ policy set matches the reviewed baseline tests/contract/policies.spec.ts:21
ISS-422Punch times are stored 5½ hours ahead (IST wall time saved as UTC)Attendanceclock-inOpen — reproducesStore real UTC (05:16:51Z), or store local time without a Z, together with the employee's time zone.
server "now" 2026-10-15T00:14:28Z vs real UTC 2026-10-14T18:44:28.537Z expect(received).toBeLessThan(expected) Expected: < 10 Received: 329.99105
full error

ISS-422 · punch times are stored as real UTC

Error: server "now" 2026-10-15T00:14:28Z vs real UTC 2026-10-14T18:44:28.537Z

expect(received).toBeLessThan(expected)

Expected: < 10
Received:   329.99105
1 test: 1 fail
tests
  • ✗ ISS-422 · punch times are stored as real UTC tests/contract/data-integrity.spec.ts:15
ISS-444Managers, department heads and HR SPOC are offered Bulk assign and roster edits, but every save is refused (403) with no messageAttendanceShifts & rostersOpen — reproducesEither give these roles roster rights (the sheet has reporting managers build and assign the roster, and HR SPOC configure shifts), or hide Bulk assign / Upload roster / chip editing for them. In any case, show the refusal in the dialog.
expect(received).toBe(expected) // Object.is equality Expected: false Received: true
full error

ISS-444 · mgr can save the roster it is shown (rows 36–37)

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true

ISS-444 · dh can save the roster it is shown (rows 36–37)

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true

ISS-444 · spoc can save the roster it is shown (rows 36–37)

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true
3 tests: 3 fail
tests
  • ✗ ISS-444 · mgr can save the roster it is shown (rows 36–37) tests/contract/permissions.spec.ts:41
  • ✗ ISS-444 · dh can save the roster it is shown (rows 36–37) tests/contract/permissions.spec.ts:41
  • ✗ ISS-444 · spoc can save the roster it is shown (rows 36–37) tests/contract/permissions.spec.ts:41
ISS-445My attendance says "Off today — enjoy the day" on a working day, and a holiday gets a rostered shiftAttendanceMy attendanceOpen — reproduces"Your shift" shows today's rostered shift on a working day; bulk assign skips holidays (or warns), and the schedule shows the holiday.
expect(locator).not.toContainText(expected) failed Locator: locator('#main-content').getByText('Your shift', { exact: true }).locator('xpath=ancestor::*[3]') Expected pattern: not /Off today/ Received string: "Your shiftFrom your team’s work scheduleSwap a shiftOff today — enjoy the dayGeneral hoursSwap with QA Employee Two · in 6 days · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap …
morewith QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · 12 Nov · approvedSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 29 Oct · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 11 Nov · approvedSwap with QA Employee Two · 11 Nov · cancelledSwap with QA Employee Two · 16 Nov · cancelledSwap with QA Employee Two · 27 Oct · rejectedSwap with QA Employee Two · 26 Oct · cancelledSwap with QA Employee Two · 28 Oct · cancelledSwap with QA Employee Two · 17 Nov · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 18 Nov · approvedSwap with QA Employee Two · 3 Nov · cancelledSwap with QA Employee Two · 18 Nov · cancelledSwap with QA Employee Two · 11 Nov · rejectedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 22 Oct · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · in 6 days · approved" Timeout: 30000ms 63 × locator resolved to <div class="rounded-lg border border-edge bg-surface shadow-xs">…</div>
full error

ISS-445 · "Your shift" shows the shift on a working day, not "Off today"

Error: expect(locator).not.toContainText(expected) failed

Locator: locator('#main-content').getByText('Your shift', { exact: true }).locator('xpath=ancestor::*[3]')
Expected pattern: not /Off today/
Received string: "Your shiftFrom your team’s work scheduleSwap a shiftOff today — enjoy the dayGeneral hoursSwap with QA Employee Two · in 6 days · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · 12 Nov · approvedSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 29 Oct · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 11 Nov · approvedSwap with QA Employee Two · 11 Nov · cancelledSwap with QA Employee Two · 16 Nov · cancelledSwap with QA Employee Two · 27 Oct · rejectedSwap with QA Employee Two · 26 Oct · cancelledSwap with QA Employee Two · 28 Oct · cancelledSwap with QA Employee Two · 17 Nov · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 18 Nov · approvedSwap with QA Employee Two · 3 Nov · cancelledSwap with QA Employee Two · 18 Nov · cancelledSwap with QA Employee Two · 11 Nov · rejectedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 22 Oct · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · in 6 days · approved"
Timeout: 30000ms

Call log:
  - Expect "not toContainText" locator('#main-content').getByText('Your shift', { exact: true }).locator('xpath=ancestor::*[3]') with timeout 30000ms
  - waiting for locator('#main-content').getByText('Your shift', { exact: true }).locator('xpath=ancestor::*[3]')
    63 × locator resolved to <div class="rounded-lg border border-edge bg-surface shadow-xs">…</div>
       - unexpected value "Your shiftFrom your team’s work scheduleSwap a shiftOff today — enjoy the dayGeneral hoursSwap with QA Employee Two · in 6 days · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · 12 Nov · approvedSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 29 Oct · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 11 Nov · approvedSwap with QA Employee Two · 11 Nov · cancelledSwap with QA Employee Two · 16 Nov · cancelledSwap with QA Employee Two · 27 Oct · rejectedSwap with QA Employee Two · 26 Oct · cancelledSwap with QA Employee Two · 28 Oct · cancelledSwap with QA Employee Two · 17 Nov · cancelledSwap with QA Employee Two · 4 Nov · rejectedSwap with QA Employee Two · 18 Nov · approvedSwap with QA Employee Two · 3 Nov · cancelledSwap with QA Employee Two · 18 Nov · cancelledSwap with QA Employee Two · 11 Nov · rejectedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 23 Oct · approvedSwap with QA Employee Two · 22 Oct · cancelledSwap with QA Employee Two · 12 Nov · cancelledSwap with QA Employee Two · 22 Oct · rejectedSwap with QA Employee Two · in 6 days · approved"
1 test: 1 fail
tests
  • ✗ ISS-445 · "Your shift" shows the shift on a working day, not "Off today" tests/contract/data-integrity.spec.ts:62
ISS-437/439(follow-up to ISS-437) The manager-approved request with unpaid days ends as "Rejected" after the posting retries run outLeaveledger postingOpen — reproducesThe request is posted as 1.25 days PTO + 1.75 days loss of pay and ends Approved. A system failure after approval should never look like the manager's rejection.
timed out waiting for request decided
full error

ISS-437/439 · approved leave with confirmed unpaid days is posted and stays approved (row 15)

Error: timed out waiting for request decided
1 test: 1 fail
tests
  • ✗ ISS-437/439 · approved leave with confirmed unpaid days is posted and stays approved (row 15) tests/journeys/al04-al05-leave.spec.ts:201
ISS-440Balances show a male employee with 182 days of Maternity Leave, and annual leave types credited twiceLeavebalances & accrualOpen — reproducesGender-restricted types are credited only to eligible employees, and each annual entitlement is credited once per year (Wedding 7, Floating 2, Bereavement 10).
expect(received).toEqual(expected) // deep equality - Expected - 1 + Received + 6 - Array [] + Array [ + "Aarav Krishnamurthy.: maternity 182", + "Kavya Raghunathan: paternity 5", + "Test Interviewer One: paternity 5", + "Test Interviewer Two: maternity 182", + ]
full error

ISS-440 · nobody is credited leave types restricted to another gender, or more than the yearly entitlement

Error: expect(received).toEqual(expected) // deep equality

- Expected  - 1
+ Received  + 6

- Array []
+ Array [
+   "Aarav Krishnamurthy.: maternity 182",
+   "Kavya Raghunathan: paternity 5",
+   "Test Interviewer One: paternity 5",
+   "Test Interviewer Two: maternity 182",
+ ]
1 test: 1 fail
tests
  • ✗ ISS-440 · nobody is credited leave types restricted to another gender, or more than the yearly entitlement tests/contract/data-integrity.spec.ts:22
ISS-446PTO credited in the joining month despite the policy's 30-day wait (and shown rounded as 1.3d)LeaveaccrualOpen — reproducesNo PTO credit before the waiting period ends (first credit 1 Nov for a 1 Oct joiner); ledger amounts shown to two decimals.
expect(received).toEqual(expected) // deep equality - Expected - 1 + Received + 3 - Array [] + Array [ + "2026-10-09 1.25 policy_entitlement:2026-10", + ]
full error

ISS-446 · no PTO is credited before the policy’s waiting period ends

Error: expect(received).toEqual(expected) // deep equality

- Expected  - 1
+ Received  + 3

- Array []
+ Array [
+   "2026-10-09 1.25 policy_entitlement:2026-10",
+ ]
1 test: 1 fail
tests
  • ✗ ISS-446 · no PTO is credited before the policy’s waiting period ends tests/contract/data-integrity.spec.ts:45
ISS-447Service Leave's policy form can't show its anniversary rule: blank accrual, "Entitlement can't be negative", list says "—d / year"LeavepoliciesOpen — reproducesThe form supports the rule it stores: anniversary accrual, days per year of service, a yearly maximum, expiry months, and shows "2 days per year of service, up to 10" in the list.
expect(locator).toHaveCount(expected) failed Locator: getByRole('dialog').filter({ hasText: /Edit policy/ }).last().getByText(/Entitlement can't be negative/) Expected: 0 Received: 1 Timeout: 30000ms 62 × locator resolved to 1 element
full error

ISS-447 · the Service Leave policy form shows its rule without a validation error

Error: expect(locator).toHaveCount(expected) failed

Locator:  getByRole('dialog').filter({ hasText: /Edit policy/ }).last().getByText(/Entitlement can't be negative/)
Expected: 0
Received: 1
Timeout:  30000ms

Call log:
  - Expect "toHaveCount" getByRole('dialog').filter({ hasText: /Edit policy/ }).last().getByText(/Entitlement can't be negative/) with timeout 30000ms
  - waiting for getByRole('dialog').filter({ hasText: /Edit policy/ }).last().getByText(/Entitlement can't be negative/)
    62 × locator resolved to 1 element
       - unexpected value "1"
1 test: 1 fail
tests
  • ✗ ISS-447 · the Service Leave policy form shows its rule without a validation error tests/contract/data-integrity.spec.ts:76
ISS-450PTO policy changed on the tenant: the 30-day waiting period was replaced by "start next month", and the October credit staysLeavepoliciesOpen — reproducesChanges to the policy rules are intended and reviewed, and the 30-day wait (handbook / sheet rows 48–51) is kept or replaced on purpose. Credits that conflict with the current rule are reversed.
expect(received).toMatchObject(expected) - Expected - 1 + Received + 0 Object { "frequency": "monthly", "rate": 1.25, - "waitingDays": 30, }
full error

PTO: 1.25 days a month after 30 days, carry-forward 30, LOP fallback (rows 48–51, 60)

Error: expect(received).toMatchObject(expected)

- Expected  - 1
+ Received  + 0

  Object {
    "frequency": "monthly",
    "rate": 1.25,
-   "waitingDays": 30,
  }
1 test: 1 fail
tests
  • ✗ PTO: 1.25 days a month after 30 days, carry-forward 30, LOP fallback (rows 48–51, 60) tests/contract/policies.spec.ts:28
ISS-453A pending Leave Without Pay request can't be withdrawn: "Protected run… forced by the platform tier"Leavemy leaveOpen — reproducesSheet row 18: an employee can withdraw any pending request at once. A platform-enforced workflow may stop the company from editing or rerouting the run, but not stop the requester from withdrawing it. If withdrawal really isn't allowed, don't offer "Cancel thi…
mores request", and explain it in plain words.
timed out waiting for request withdrawn
full error

ISS-453 · a pending Leave Without Pay request can be withdrawn (row 18)

Error: timed out waiting for request withdrawn
1 test: 1 fail
tests
  • ✗ ISS-453 · a pending Leave Without Pay request can be withdrawn (row 18) tests/journeys/al04-al05-leave.spec.ts:181
ISS-441"Request comp-off" (earning a day for weekend work) is rejected for having no comp-off balanceOvertime & comp-offComp-Off Request workflowOpen — reproducesA request to earn comp-off goes to the reporting manager (and HR head, per the sheet), and on approval credits the day to the Comp-off balance with its 90-day expiry.
expect(received).toBe(expected) // Object.is equality Expected: false Received: true timed out waiting for manager task
full error

ISS-441 · earning comp-off does not require an existing comp-off balance

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true

ISS-441 · a request to earn comp-off for a weekend reaches the manager (rows 29–30)

Error: timed out waiting for manager task
2 tests: 2 fail
tests
  • ✗ ISS-441 · earning comp-off does not require an existing comp-off balance tests/contract/workflows.spec.ts:112
  • ✗ ISS-441 · a request to earn comp-off for a weekend reaches the manager (rows 29–30) tests/journeys/al08-al09-compoff-balances.spec.ts:35
ISS-452(update to ISS-436) Long leave now reaches the department head, but its 3-day threshold is still not a parameterWorkflowsleave approvalOpen — reproduceslv.long_leave_days is listed with its value (3) and source, like the other lv.* parameters, so changing it is a recorded settings change.
expect(received).toContain(expected) // indexOf Expected value: "lv.long_leave_days" Received array: ["ext.ceo_pack_sla", "ext.clearance_trigger", "ext.counteroffer_issue_sla", "ext.counteroffer_response_sla", "ext.damage_assessment_sla", "ext.escalate_to_hr_sla", "ext.exit_docs_sla", "ext.ffs_clear_sla", "ext.ffs_gratuity_target", "ext.ffs_l1", …]
full error

ISS-452 · the long-leave threshold used by leave approval is a visible parameter

Error: expect(received).toContain(expected) // indexOf

Expected value: "lv.long_leave_days"
Received array: ["ext.ceo_pack_sla", "ext.clearance_trigger", "ext.counteroffer_issue_sla", "ext.counteroffer_response_sla", "ext.damage_assessment_sla", "ext.escalate_to_hr_sla", "ext.exit_docs_sla", "ext.ffs_clear_sla", "ext.ffs_gratuity_target", "ext.ffs_l1", …]
1 test: 1 fail
tests
  • ✗ ISS-452 · the long-leave threshold used by leave approval is a visible parameter tests/contract/workflows.spec.ts:105
GAPS row 33
GAPS.md row 33
HR SPOC has no balance-adjust right on this tenant (GAPS.md row 33)AccessRoles & permissionsGap — not supportedHR SPOC can adjust special leave balances
expect(received).toBe(expected) // Object.is equality Expected: false Received: true
full error

GAPS row 33 · HR SPOC can adjust special leave balances

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true
1 test: 1 fail
tests
  • ✗ GAPS row 33 · HR SPOC can adjust special leave balances tests/contract/permissions.spec.ts:46
GAPS row 34
GAPS.md row 34
HR SPOC is view-only on leave policies on this tenant (GAPS.md row 34)AccessRoles & permissionsGap — not supportedHR SPOC can change leave configuration
expect(received).toBe(expected) // Object.is equality Expected: false Received: true
full error

GAPS row 34 · HR SPOC can change leave configuration

Error: expect(received).toBe(expected) // Object.is equality

Expected: false
Received: true
1 test: 1 fail
tests
  • ✗ GAPS row 34 · HR SPOC can change leave configuration tests/contract/permissions.spec.ts:50
GAPS row 22
GAPS.md row 22
Back-dated WFH is accepted and sent to the manager (GAPS.md row 22)AttendanceWork from homeGap — not supportedback-dated work from home is refused
expect(received).toBeGreaterThanOrEqual(expected) Expected: >= 400 Received: 201
full error

GAPS row 22 · back-dated work from home is refused

Error: expect(received).toBeGreaterThanOrEqual(expected)

Expected: >= 400
Received:    201
1 test: 1 fail
tests
  • ✗ GAPS row 22 · back-dated work from home is refused tests/journeys/al06-wfh.spec.ts:79
GAPS row 25
GAPS.md row 25
No HR SPOC step in the WFH workflow (GAPS.md row 25)AttendanceWork from homeGap — not supportedlong WFH gets an HR SPOC review
timed out waiting for HR SPOC task
full error

GAPS row 25 · long WFH gets an HR SPOC review

Error: timed out waiting for HR SPOC task
1 test: 1 fail
tests
  • ✗ GAPS row 25 · long WFH gets an HR SPOC review tests/journeys/al06-wfh.spec.ts:87
GAPS row 42
GAPS.md row 42
Eligibility does not check identical shifts (GAPS.md row 42)AttendanceShift swapGap — not supporteda swap between identical shifts is refused
expect(received).toBeGreaterThanOrEqual(expected) Expected: >= 400 Received: 201
full error

GAPS row 42 · a swap between identical shifts is refused

Error: expect(received).toBeGreaterThanOrEqual(expected)

Expected: >= 400
Received:    201
1 test: 1 fail
tests
  • ✗ GAPS row 42 · a swap between identical shifts is refused tests/journeys/al10-al11-shifts.spec.ts:100
GAPS row 43
GAPS.md row 43
No peer acceptance: the swap goes straight to the manager (GAPS.md row 43)AttendanceShift swapGap — not supportedthe teammate is asked to accept a swap first
timed out waiting for teammate task
full error

GAPS row 43 · the teammate is asked to accept a swap first

Error: timed out waiting for teammate task
1 test: 1 fail
tests
  • ✗ GAPS row 43 · the teammate is asked to accept a swap first tests/journeys/al10-al11-shifts.spec.ts:87
GAPS row 1Half-day cut-off is 4 hours on this tenant; the sheet asks for 8 (GAPS.md row 1)LeavePoliciesGap — not supporteddays under 8 hours count as half days
expect(received).toBe(expected) // Object.is equality Expected: 8 Received: 4
full error

GAPS row 1 · days under 8 hours count as half days

Error: expect(received).toBe(expected) // Object.is equality

Expected: 8
Received: 4
1 test: 1 fail
tests
  • ✗ GAPS row 1 · days under 8 hours count as half days tests/contract/policies.spec.ts:76
ISS-451"Correct a day" says nothing when the server refuses the request (e.g. a day before joining); the picker offers those daysAttendanceregularizationFixed — regression check passesThe server's message is shown in the drawer. Days before the joining date are disabled in the picker.
As expected: 1 check passed.
1 test: 1 pass
tests
  • ✓ a refused correction tells the employee why (ISS-451; the picker part is checked by SHR-014) tests/journeys/al01-al02-attendance.spec.ts:138
ISS-436Leave of three days or more skips the department head (parameter lv.long_leave_days is not defined)LeaveAnnual Leave Approval workflowFixed — regression check passesWith 3 consecutive days the request goes to Department head approval (sheet row 14: 2 levels for ≥ 3 days). The parameter should exist (default 3), or the designer should refuse to publish a condition that names a missing parameter.
As expected: 1 check passed.
1 test: 1 pass
tests
  • ✓ leave of 3 days or more goes to the department head after the manager (row 14; was ISS-436, fixed 14 Oct) tests/journeys/al04-al05-leave.spec.ts:164

Test coverage by module

ModuleSubmoduleTestsPassedFailedNot runIssues covered
AccessRoles & permissions116503
AttendanceClock in / out10100
AttendanceRegularization33001
AttendanceSettings11000
AttendanceShift swap42202
AttendanceShifts & roster11000
AttendanceWork from home64202
GeneralPages load1818000
HomeDashboard11000
LeaveApproval & cancellation33000
LeaveApproval routing11001
LeaveBalances11000
LeaveComp-off30122
LeavePolicies74302
LeaveRequest validation11000
LeaveRequests20202
Leave & AttendanceData integrity50505
ReportsDownloads22000
WorkflowsLeave & attendance workflows1917202
Total906523222