Skip to content

Test/e2e workplace concierge 2026 09 18 - #497

Draft
sharmilaseenivasan17 wants to merge 11 commits into
developfrom
test/e2e-workplace-concierge-2026-09-18
Draft

sharmilaseenivasan17 wants to merge 11 commits into
developfrom
test/e2e-workplace-concierge-2026-09-18

Conversation

@sharmilaseenivasan17

Copy link
Copy Markdown

Added E2E tests for Concierge visitor invitations, notes and induction, parking management, desk QR codes, catering, deals, and email templates. Added partial coverage for Points and Facilities, plus a survey API test while survey creation through the UI remains blocked by a bug. Updated the Excel plans with coverage counts, simple bug examples, and suggested decisions.

sharmilaseenivasan17 and others added 11 commits September 15, 2026 16:02
23 tests across 11 spec files, mirroring the existing desk coverage:
invite (single and group), cancel from the app, form validation, settings,
visitor details, times, booking for a colleague, check-in/check-out,
editing, and visibility between users.

22 pass; 1 is fixme, blocked on an app bug where saving an edit in
single-visitor mode throws and sends nothing.

Visitor support code lives in e2e/support/visitor/ so the desk specs cannot
be affected - no shared support file is changed. Also adds e2e/tsconfig.json
and a bun run e2e:typecheck script; nothing type-checked the specs before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 tests across 6 spec files, in the same shape as the desk and visitor
coverage: book through the UI, teardown, double-booking (same slot and
partial overlap, as a second user, with a control), visibility between
users, times and the limits on what may be chosen, attendees, and
cancelling from the app.

11 pass; 3 are fixme, blocked on app bugs - a room booking is stored with
no zones (ROOM-B2), the meeting length picked is not the length booked
(ROOM-B3), and cancelling from the schedule fires DELETE /events and 500s
while the room stays held (ROOM-B4).

Rooms only run locally in one mode. By default the meeting flow calls
Microsoft/Google through /events and /calendars, which 500 on the local
stack; with app.events.use_bookings = true the same form saves an ordinary
PlaceOS booking of type room, with no outbound call. So a green run proves
the PlaceOS-native room path works and says nothing about the calendar
path - E2E_USER_STORIES.md WP-E2E-15 is now partial rather than out of
scope, split along that line, and rooms have their own section 1b.

Room support code lives in e2e/support/room/ so neither the desk nor the
visitor specs can be affected, and rooms are seeded there rather than in
the shared seed.ts - a room is an engine System and must genuinely be
created. The one existing file touched is your-bookings.page.ts, where the
constructor argument becomes protected so the room schedule page can
inherit it instead of copying it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… for rooms

Seven more room tests, taking the room files from 14 tests to 22 - 17
passing, 5 blocked, 0 failing. Four new spec files:

  room-edit        change the start time; move the booking to another room
  room-capacity    strict mode refuses before anything is sent; the default
                   only warns and still books
  room-favourites  a favourite is saved to the user's own settings, and the
                   Favorites Only filter narrows the picker to it
  room-approval    the default stores the booking unapproved
  room-catering    fixme, see ROOM-B5 below

The capacity pair needs a room too small to book, and capacity belongs to
the engine System rather than to settings, so room.seed.ts now creates
three rooms per worker: a normal one, an alt one to move a booking into,
and a capacity-1 one. catering.seed.ts does the same for a catering menu,
which is made of assets - a hidden _CATERING_ category, a CATERING: asset
type and one asset on the building - all on the engine api.

ROOM-B5, a new finding: catering cannot be ordered with a PlaceOS-native
room booking at all. The meeting saves (201) and the order that follows is
refused 422 "error linking booking to event", because orders are linked to
a calendar event by id and in use_bookings mode that id is a booking id.
The room booking is then left behind undeleted and no order exists, while
the user is shown an error and has every reason to believe nothing was
booked. ROOM-B1 was re-measured through the app and still 500s.

Checking in to a room is blocked by the stack, not by effort, and has no
spec on purpose: the control needs a live Bookings driver module on the
room's System, and this stack has one driver (spec_helper) and one module
(PrivateHelper). ROOM-23 records that, and what would unblock it.

E2E_USER_STORIES.md carries ROOM-15 ... ROOM-23 and the fifth finding.
your-bookings.page.ts gains two protected hooks so the room schedule page
inherits startEdit rather than copying it - the form Edit lands on is the
only part that differs by booking type.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
24 tests in 15 new spec files, all passing: 14 for the Your Bookings page,
which had no coverage of its own, and 10 filling the desk gaps.

Your Bookings (e2e/support/bookings/, bookings-*.spec.ts)
  the listing, per type and per day, plus what it asks the backend for
  the five type filters, and the chips beside them
  cancelling from the list, and declining the confirmation
  Edit routing to the right form per booking type
  checking in to a desk booking and back out
  a finished booking offers no check-in
  an empty day shows its empty state
  another user's bookings never appear, with a control

Desks (e2e/support/desk/, desk-*.spec.ts)
  the day, start time and length chosen are the ones stored
  a maximum length and bookable hours limit what is offered
  editing the time, and moving the booking to another desk
  an all-day booking is stored as all-day
  booking for a colleague stores them as user and you as booker
  a favourite desk is saved against the user
  a bad booking request is refused 4xx, never 5xx
  a clash check uses the current booking_end (REG-03, now covered)
  the checked-in badge appears only once checked in (REG-04)

Both areas keep their own support folder and share nothing with each other
or with visitor/ and room/. The schedule page object still belongs to
visitor/your-bookings.page.ts, which introduced it; bookings/ and desk/
inherit it, and the form Edit lands on is now a settable hook because on
that page it depends on the booking rather than the page.

Three things measured along the way, recorded where they cost time:

- The schedule sends include_deleted=true and renders cancelled bookings
  for ever, so the number of cards on a day grows with every run. Card
  counts are therefore never asserted; the specs compare against what the
  backend says is live.
- POST /bookings can return 201 with an id for a booking that does not
  exist: GET on that id then 404s. That is REG-09 doing more damage than
  its row describes, and every create here reads the row back.
- The desk host field searches /api/staff/v1/people, the calendar
  directory, which 500s on this stack. app.basic_user_search switches it
  to the local user list, so DESK-14 covers the PlaceOS path only.

Also: the desk form's date picker needs a converging open (the form is
rebuilt underneath the click), and the schedule's sidebar calendar only
reaches the displayed month - so desk slots stay within four days of today
and separate by hour instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 tests in 8 spec files: 13 passing, 1 blocked. Parking was the last
booking type in workplace with no coverage at all.

  parking-booking      book through the full UI; teardown really tears down
  parking-clash        same window and partial overlap refused 409 as a
                       second user, with a control; the space frees up again
  parking-scoping      another user cannot see or delete yours, with a control
  parking-times        the day, start and length chosen are the ones stored;
                       limits control what is offered
  parking-cancel       cancelling from the app really removes it; declining
                       the confirmation does not
  parking-edit         change the time; move the booking to another space
  parking-favourites   a favourite space is saved against the user
  parking-api          a bad request is refused 4xx, never 5xx
  parking-restrictions fixme - PARK-B1 below

Parking needed the most seeding of any resource here, and none of it is in
the shared seed.ts: parking.seed.ts creates a level zone tagged `parking`,
the hidden _PARKING_ asset category, the _PARKING_SPACES_ asset type, and
one space per worker plus a spare. A NEW level zone rather than a tag on
the seeded one, so the desks' data is untouched.

PARK-B1, a new finding: with `parking.require_space_restriction` on, the
ordinary parking booking form cannot be submitted at all. The validator
lives in the shared booking form and fires for any parking booking, while
the parking booking form never renders a `space_restrictions` control - so
Confirm Reservation answers "Some fields are invalid.
[space_restrictions]" naming a field that is not on screen. The setting's
own schema describes it as belonging to the parking REQUEST flow, which
does render one. Measured on this stack with no overrides, which blocked
the whole area until the setting was turned off in PARKING_BASE_SETTINGS.

Also recorded where it cost time: the parking confirm step is a BOTTOM
SHEET in the CDK overlay, not a routed view like the desk and meeting
flows; the picker's favourite control is a bare `fav` attribute; and the
favourites key is `favourite_parking_spaces`, not the `favourite_parking`
constant in libs/common that nothing reads.

The backend accepts a booking against an asset id that does not exist, for
parking and for desks alike. Recorded in both API specs as a warning
rather than a failure - it may be worth a bug of its own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
11 tests in 6 spec files: 8 passing, 3 blocked. The home page had nothing
of its own - boot.spec.ts proves the shell renders, which says nothing
about whether the panels show the right data.

  home-upcoming     a booking later today is listed; View all hands off to
                    Your Bookings with the booking findable there
  home-colleagues   a colleague added from the sidebar is saved; removing
                    one clears it
  home-favourites   a favourite desk is listed on the Favourites tab;
                    removing it there clears the saved setting
  home-scoping      another user's booking never appears, with a control
  home-quick-book   fixme - HOME-B2 below
  home-availability fixme - blocked by the stack, below

Three things measured that shaped the tests:

- "Upcoming" means TODAY and nothing else. The panel is built from the
  schedule's own list filtered to `isSameDay(date, now)` and sliced to
  five. A first draft booked sixteen days out and spent three failures
  finding that out.

- HOME-B1, a new finding: the panel keeps showing bookings you cancelled.
  It inherits the schedule's include_deleted=true query and only hides
  what was cancelled in the current session. Measured: five cards, every
  one cancelled, while a live booking for the same user and day was
  absent - the junk had crowded it out of the five slots. So it both tells
  users they have a desk they cancelled AND can hide a real one.

- HOME-B2, a new finding: the one-click quick-book tile spins for ever and
  books nothing. GET /calendars 500s here (the calendar surface this suite
  does not cover), and `book()` awaits listAvailableResources outside any
  try/catch - so the rejection kills the handler after the loading flag is
  set, leaving a permanent spinner and no message. A misconfigured tenant
  would look like this in production.

The availability panel is blocked by the stack rather than by a bug: it
lists only rooms a live driver binding reports as free, and this stack has
one driver (spec_helper) and one module (PrivateHelper). Same blocker as
room check-in (ROOM-23).

Also recorded where each cost a run: the colleague list is its own
`contacts` metadata document, NOT the favourite_team_members key that
libs/common advertises; the sidebar tabs are reached by their material
ligatures (people, favorite) because neither button has a name; and
colleague rows are labelled with display names, so lookups normalise both
sides before comparing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nine more tests: 3 passing, 6 written and skipped against defects they
guard. Plus a REG-09 retry for the room booking flow, which was the last
place in the suite without one.

Passing
  parking-levels    a space on a level that is not tagged `parking` is not
                    offered, with a control that the properly-placed one is

Guards for findings, written and skipped
  room-multi        ROOM-B6 (new): a two-room meeting books ONE room. Both
                    rooms show on the form, the meeting is accepted, and
                    only the first is held - so the second stays bookable
                    and everyone sent to it finds it occupied.
  room-allday       ROOM-B7 (new): the all-day flag is ignored. With the
                    checkbox proven still ticked at send time, the stored
                    booking is one hour long.
  room-delegate     ROOM-B8 (new): the chosen host is discarded. With the
                    field proven to still show the colleague at send time,
                    the booking comes back owned by the booker. Desks get
                    this right (DESK-14 is green), which is the useful
                    comparison.
  visitor-duplicate VIS-B1's guard. Red-checked: the second identical
                    invite returns 201.
  visitor-group-clash VIS-B9's guard. Red-checked: 409 Conflicting booking
                    on a `group` row named `${host}[${creation date}]`,
                    which is the mechanism itself, visible in the response.
  home-upcoming     HOME-B1's second facet: a live booking is crowded off
                    the five-slot panel by cancelled ones.

All three new room findings were proven to be the app discarding input
rather than the form reverting it: `bookRoomViaUI` now asserts the All Day
checkbox and the host field still hold their values immediately before the
meeting is confirmed. Without that, "the booking came back wrong" has two
indistinguishable causes and neither could be reported honestly.

Two things that shaped the tests rather than the app:

- The meeting form's all-day control is `events.allow_all_day`, in
  meeting-form-details.component.ts - NOT `allow_multiday`, which only
  widens the picker's dates. A first attempt looked for a checkbox that
  was never going to be there.
- Multi-select rooms confirm with `space-return` and the add button starts
  DISABLED, enabling only once a row click registers. Checking isEnabled
  immediately silently adds one room instead of two.

The home page's Upcoming panel cannot be relied on to show a live booking
while HOME-B1 stands, so the scoping control proves the same property on
Your Bookings instead of losing the control altogether.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ures

Five more workplace tests: 4 passing, 1 parked.

  parking-access    a user marked `deny` cannot book, and can again once the
                    flag is cleared. The flag is an asset, and its value is
                    the STRING 'true' - a real boolean never registers.
  parking-request   a submitted request is stored as a parking booking
                    against an `unallocated-*` asset, the only parking
                    booking that holds no real space.
  desk-scoping      DESK-15, which was blocked on a seeding change. The
                    extra level is created by the spec and deleted
                    afterwards, so the shared seed.ts stays untouched.
  room-features     the picker's facilities filter narrows to the room that
                    has the feature. room.seed.ts now puts one feature on
                    the `alt` room, because the filter section is not
                    rendered at all when no room carries anything.
  home-meeting-with the colleague shortcut opens the meeting form with that
                    person already invited.
  home-errors       fixme: the home page raises an unhandled rejection on
                    load from the calendar 500s (HOME-B2).
  room-rules        fixme, and UNRESOLVED: a `hidden` booking rule has no
                    effect, and I have not established whether the ruleset
                    shape is wrong or the picker ignores it. The docblock
                    records what was measured and the one-run way to settle
                    it (window.debug_booking_rules).

Two API details learned and written down: a System PATCH needs `version`
in the QUERY STRING (in the body it is ignored and the request 422s), and
booking rules are read from the BUILDING's own metadata document even
though the request reads like a query about its children.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Passing. A group invite is a container plus one booking per person, so an
edit that updated only the container, or only the member it was opened
from, would leave half a party expected at the old time and reception
turning people away.

Three things this cost, all now written into the spec:

- inviteVisitorsViaUI returns the CONTAINER as well as the members - three
  bookings for two visitors - so the members are picked out by asset
  address.
- The container has to be swept in teardown as well as the members. It is
  not returned by the flow, and because every group invite a host makes in
  a day shares one asset id (VIS-B9), one leftover container makes the next
  three runs of this test impossible.
- The flow's `date` option chooses a DAY, not a time, so the starting hour
  is read back rather than assumed.

Also corrected visitor-group-clash to build its container id the way the
app does - `${host}[${YYYY-MM-DD}]`, measured from a real invite - rather
than with toDateString().

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
frontend-templates Ignored Ignored Sep 18, 2026 1:29pm UTC

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@sharmilaseenivasan17
sharmilaseenivasan17 requested review from MrYuion and w-le and removed request for MrYuion September 18, 2026 13:29
@sharmilaseenivasan17
sharmilaseenivasan17 marked this pull request as draft September 18, 2026 13:30

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant