1
0
mirror of https://github.com/quay/quay.git synced 2026-01-26 06:21:37 +03:00
Commit Graph

293 Commits

Author SHA1 Message Date
jbpratt
391e5204f8 feat(web): add immutability policies UI for orgs and repos (PROJQUAY-10163) (#4942)
Add UI components for managing immutability policies at both organization
and repository levels. Features include:
- Unified table displaying namespace and repository policies with scope
- Inline editing for policies with pattern validation
- "Add Policy" button positioned next to title header
- Inherited namespace policies shown in repository settings
- Comprehensive Playwright e2e tests

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-22 14:19:46 -06:00
Shaon H
92b6f4729a feat(mirror): organization-level mirror config CRUD APIs (PROJQUAY-1266) (#4923)
* mirror: Add FEATURE_ORG_MIRROR feature flag (PROJQUAY-1266)

Add organization-level repository mirroring feature flag to enable
the new org mirroring functionality. Feature is disabled by default.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* mirror: Add GET endpoint for org mirror config (PROJQUAY-1266)

Implements the GET /v1/organization/<org>/mirror endpoint to retrieve
organization-level mirror configuration. Includes business logic layer
with get_org_mirror_config() and comprehensive unit tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* mirror: Add POST endpoint for org mirror config (PROJQUAY-1266)

Add create endpoint for organization-level mirror configuration:
- POST /v1/organization/<orgname>/mirror creates new config
- Validates robot account ownership and credentials
- Returns 201 on success, 409 if config already exists

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* mirror: Add DELETE endpoint for org mirror config (PROJQUAY-1266)

Add delete endpoint for organization-level mirror configuration:
- DELETE /v1/organization/<orgname>/mirror removes config
- Also deletes all associated discovered repositories
- Returns 204 on success, 404 if config doesn't exist

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* mirror: Add PUT endpoint for org mirror config (PROJQUAY-1266)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix test failure

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 16:01:15 -08:00
jbpratt
8f34343102 feat(web): tag immutability UI (PROJQUAY-10163) (#4925)
Implement React/PatternFly UI for tag immutability features:
- Lock icon display for immutable tags with tooltip
- Make immutable action in kebab menu
- Remove immutability action for superusers
- Confirmation modal for toggling immutability
- Disable delete/expiration actions for immutable tags
- Bulk actions: make immutable, skip immutable on delete
- All UI gated behind IMMUTABLE_TAGS feature flag
- Playwright e2e tests for all functionality

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:57:16 -06:00
jbpratt
4a4d17fbda fix(web): clean up PluginMain (PROJQUAY-9124) (#4881)
* fix(web): remove plugin auth issues banner (PROJQUAY-9124)

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* fix(web): wrap PluginMain in UIProvider (PROJQUAY-0000)

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
2026-01-16 08:19:59 -06:00
jbpratt
8851add610 test(web): migrate signin.cy.ts to Playwright (#4851)
Migrate 30 Cypress signin tests to 19 Playwright tests with:
- Real API for invalid credentials, unverified email, global messages
- Mocked routes for CSRF errors, 500 errors, recovery responses
- Feature tags: @feature:MAILING, @feature:USER_CREATION, etc.
- 7 data-testid attributes added to Signin.tsx for stable selectors

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-14 08:21:24 -08:00
jbpratt
2109cfeba2 test(web): migrate usage-logs e2e tests to Playwright (#4844)
Migrate web/cypress/e2e/usage-logs.cy.ts to Playwright, converting
13 Cypress tests to 10 consolidated Playwright tests across two files:

- playwright/e2e/usage-logs.spec.ts (6 tests): Organization and
  repository usage logs including chart toggle, log export, email
  validation, filtering, and Splunk error handling

- playwright/e2e/superuser/usage-logs.spec.ts (4 tests): Superuser
  usage logs page with columns, chart toggle, filtering, and Splunk
  error handling

Key changes:
- Add data-testid attributes to UsageLogsExportModal (export button,
  confirm button, email input), UsageLogsTable (filter input), and
  both UsageLogs components (chart toggle button)
- Use real API data instead of mocking (except Splunk 501 errors)
- Use getByPlaceholder for SearchInput since PatternFly wraps the
  actual input element
- Handle duplicate error messages with .first() selector

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 12:01:45 -08:00
Harish Govindarajulu
5d6549327a feat(web): add Recent Repo Builds to Information tab (PROJQUAY-9851) (#4829)
* feat(web): add Recent Repo Builds to Information tab (PROJQUAY-9851)

* Address code rabbit reviews

* Fix build view alignment

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-13 16:17:33 +00:00
jbpratt
3c5fd96d4b test(web): migrate update-user tests from Cypress to Playwright (#4788)
Migrate UpdateUser page tests following MIGRATION.md patterns:
- Add unauthenticatedPage fixture to fixtures.ts for anonymous tests
- Add data-testid attributes to UpdateUser.tsx for stable selectors
- Create update-user.spec.ts with profile metadata tests
- Include mailpit email verification for FEATURE_MAILING support

Consolidates 7 Cypress tests to 4 Playwright tests (3 passing, 1 skipped).
OAuth username confirmation tests marked TODO for future implementation.

Signed-off-by: Brady Pratt <bpratt@redhat.com>
2026-01-07 13:29:59 -06:00
jbpratt
31e8f5ff21 test(web): more playwright migrations (#4775)
* test(web): migrate quota to Playwright

Migrate quota.cy.ts (27 tests) to Playwright, consolidating to 7 focused
tests with real API interactions instead of mocks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): add missing method and fix exports

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): migrate account-settings to Playwright

Migrate 31 Cypress tests from account-settings.cy.ts to Playwright,
consolidating them into 20 well-structured tests.

Changes:
- Create user/account-settings.spec.ts with comprehensive coverage
- Add data-testid attributes to BillingInformation, CLIConfiguration,
  and GeneralSettings components
- Extend QuayConfig interface with external_login and registry_state
- Update MIGRATION.md to mark migration complete

Test coverage includes:
- General settings (email validation, profile fields)
- Tag expiration picker (@feature:CHANGE_TAG_EXPIRATION)
- Billing information (@feature:BILLING)
- CLI token generation with all credential formats
- Password change, account type, desktop notifications
- Application tokens lifecycle (create, view, revoke)
- Email change modal (@feature:MAILING)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web): enable missing features in dev config

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): migrate org-list to Playwright

Migrate organization list Cypress tests to Playwright, consolidating
22 tests into 10 focused test cases.

Tests cover:
- Search and filtering (basic + regex)
- Pagination
- Organization CRUD lifecycle (PROJQUAY-9948, PROJQUAY-9843)
- Avatar display (PROJQUAY-9749)
- Superuser status labels
- Superuser API fallback and deduplication
- Read-only superuser permissions
- Quota display and registry size (PROJQUAY-9641, PROJQUAY-9886, PROJQUAY-9860, PROJQUAY-9874)

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-07 10:09:55 -06:00
jbpratt
8e037dbc12 fix(web): hide robot creation when ROBOTS_DISALLOW is enabled (PROJQUAY-7313) (#4694)
* fix(web): hide robot creation when ROBOTS_DISALLOW is enabled (PROJQUAY-7313)

When ROBOTS_DISALLOW is enabled, robot creation UI elements are now
hidden instead of allowing users to click them and receive an error.
This provides better UX by preventing actions that cannot succeed.

Changes:
- Expose ROBOTS_DISALLOW to frontend via CLIENT_WHITELIST
- Hide "Create robot account" option in team wizard dropdown
- Hide "Create robot account" button in Robot Accounts tab
- Add defensive error handling in AddTeamMember.tsx

Co-authored-by: Claude <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* fix(web): use exact match for heading locator in superuser test (PROJQUAY-7313)

The Messages page heading locator was matching both "Messages" and
"No Messages" headings, causing a strict mode violation. Adding
exact: true ensures only the exact heading text is matched.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-06 17:04:19 -06:00
jbpratt
c6eb6b573d test(web): migrate more tests to playwright (#4773)
* test(web): migrate superuser-org-actions.cy.ts to Playwright

Migrate Cypress E2E tests for superuser organization actions to Playwright
following the project's MIGRATION.md guidelines.

Changes:
- Add new test file: playwright/e2e/superuser/org-actions.spec.ts
- Consolidate 12 Cypress tests into 5 focused Playwright tests
- Use real API data instead of mocked fixtures
- Auto-cleanup via TestApi fixture

Test coverage:
- Superuser sees actions column and options menu for organizations
- Regular user does not see organization options menu
- Superuser can rename organization
- Superuser can delete organization
- Superuser can take ownership of organization

Skipped from migration:
- Quota menu tests (already covered by quota.spec.ts)
- Fresh login requirement tests (low value, complex to mock)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web): set superuser feature tag

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): migrate superuser-messages.cy.ts to Playwright

Migrate superuser messages tests from Cypress to Playwright, consolidating
14 original tests into 6 focused, value-add tests.

Tests cover:
- Non-superuser redirect to organization page
- Full CRUD flow: create, view, and delete messages via UI
- Error state when API fails to load messages
- Loading spinner during message fetch
- Read-only superuser can access and view messages
- Read-only superuser sees disabled create/delete actions

Infrastructure additions:
- Add message() method to TestApi with auto-cleanup
- Add CreatedMessage interface for type safety
- Add SUPERUSERS_FULL_ACCESS feature tag

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web): migrate superuser-user-management.cy.ts to Playwright

Consolidates 29 Cypress tests into 11 Playwright tests covering
superuser user management functionality.

Changes:
- Add CreatedUser interface and user() method to TestApi for
  user creation with auto-cleanup
- Add createUserAsSuperuser() to API client using superuser endpoint
- Add QuayAuthType and skipUnlessAuthType() helper for auth-type
  conditional tests
- Create user-management.spec.ts with consolidated tests

Tests cover:
- Create user via UI (Database/AppToken auth only)
- User access control based on user type
- Change email and password (Database auth only)
- Toggle user status (disable/enable)
- Delete user
- Take ownership (convert user to org)
- Fresh login error handling with mocked responses
- Send recovery email (MAILING feature)
- Auth type visibility

Key patterns:
- Uses search to find users in paginated list
- page.route() only for error scenarios per MIGRATION.md
- skipUnlessAuthType() for auth-dependent tests
- @feature:SUPERUSERS_FULL_ACCESS tag for all tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): delete more migrated cypress tests

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): migrate superuser-framework Cypress test to Playwright

Consolidates 7 Cypress tests into 4 Playwright tests covering:
- Superuser navigation to all superuser pages
- Navigation section visibility and expansion
- Organizations table Settings column and actions menu
- Regular user restrictions and redirects

Uses real superuserPage/authenticatedPage fixtures instead of mocking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate superuser-service-keys Cypress test to Playwright

Consolidates 17 Cypress tests into 5 Playwright tests:
- non-superuser redirect to organization page
- superuser CRUD lifecycle (create, view, search, update, delete)
- error handling when create fails
- read-only superuser permission restrictions
- bulk select and delete operations

Adds service key API methods to Playwright test utilities:
- getServiceKeys, createServiceKey, updateServiceKey, deleteServiceKey
- TestApi.serviceKey() with auto-cleanup support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web): migrate superuser-change-log Cypress test to Playwright

Migrate superuser-change-log.cy.ts to Playwright with test consolidation:
- 7 original tests reduced to 2 focused tests
- Access control tests already covered by framework.spec.ts
- Loading spinner and empty state tests skipped (low value)
- Uses real API calls except for error state (acceptable mock)
- No PatternFly class dependencies, uses role-based selectors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web): migrate superuser-usage-logs Cypress test to Playwright

- Consolidate 7 Cypress tests into 2 Playwright tests
- Access control tests already covered by framework.spec.ts
- Add data-testid="usage-logs-table" to UsageLogsTable component
- Tests verify: page header, date pickers, chart toggle, table loading,
  and filter functionality
- Use structural assertions for parallel test safety

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): remove unneeded comments

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 17:54:25 -06:00
jbpratt
c53a584264 fix(web): prevent signin page redirect loop (PROJQUAY-10090) (#4770)
When FEATURE_ANONYMOUS_ACCESS is disabled, API calls like /api/v1/messages
return 401. The axios interceptor was unconditionally redirecting to /signin
on 401 errors, causing an infinite loop when already on auth pages.

Now checks if on /signin, /createaccount, or /oauth before redirecting.

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-05 16:27:04 -06:00
Sunandadadi
79a628cd85 fix(web): display correct robot account permissions in modal (PROJQUAY-10084) (#4766)
* fix(web): display correct robot account permissions in modal (PROJQUAY-10084)

Fix race condition in DropdownWithDescription where the permission
dropdown was incorrectly defaulting to 'Read' when loading existing
robot account permissions.

The issue occurred because rows were being marked as selected before
the actual permission values were loaded, causing the dropdown to
trigger its default 'Read' behavior.

The fix:
- Prioritize valid permission values when they exist
- Only default to 'Read' when user manually selects a row (isUserEntry=true)
- Do not default to 'Read' during auto-selection from loading existing perms

Also adds Playwright tests to verify:
- Initial permission displays correctly
- Write permission displays correctly (not defaulting to Read)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(web): pass isWizardStep to dropdown for proper permission defaults (PROJQUAY-10084)

- Pass isWizardStep prop from AddToRepository to DropdownWithDescription
- In wizard mode, always default to 'Read' when a row is selected
- In non-wizard mode (robot permissions modal), only show actual values
- Fix prettier formatting in robot-accounts.spec.ts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* minor fix

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-05 20:32:33 +00:00
jbpratt
0638c19183 test(web): migrate more tests to playwright (#4767)
* test(web): migrate repository-autopruning to Playwright

Consolidate 17 Cypress tests into 6 Playwright tests:
- policy lifecycle (create, update, delete)
- policy with tag pattern filter
- multiple policies lifecycle
- namespace policy display in repository settings
- registry policy display
- error handling (load failure)

Uses @feature:AUTO_PRUNE tag for automatic test skipping.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test: enable features by default

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): migrate create-account.cy.ts to Playwright

Migrates the Create Account Cypress tests to Playwright following
the MIGRATION.md guide:

- Consolidates 10 Cypress tests into 6 focused Playwright tests
- Uses real API calls instead of mocks
- Adds data-testid attributes to CreateAccount component
- Uses @feature:MAILING and @feature:QUOTA_MANAGEMENT tags
  to skip tests when features are not enabled
- Creates custom fixtures for unauthenticated page access
- Implements proper user cleanup after tests

Tests:
- form validation prevents invalid submissions
- creates account with valid inputs and redirects
- shows error for existing username
- navigates to signin page via link
- shows verification message (requires MAILING)
- redirects to updateuser (requires QUOTA_MANAGEMENT)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* chore(dev) add Mailpit for local email testing

Add Mailpit email testing server to the local development environment
to enable testing of FEATURE_MAILING functionality with Playwright.

Changes:
- Add mailpit service to docker-compose.yaml (ports 8025/1025)
- Enable FEATURE_MAILING and configure SMTP settings in config.yaml
- Add mailpit utilities to Playwright fixtures (getEmails, clearInbox,
  waitForEmail, getEmailBody, isAvailable)

Usage:
  podman-compose up mailpit -d
  # Access Web UI at http://localhost:8025

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test(web) use mailpit helpers for email confirmation support

Test updates:
- "creates account and redirects to organization" now confirms email
- "redirects to updateuser when user has prompts" now confirms email
- Tests detect FEATURE_MAILING at runtime and adapt accordingly
- Email search uses recipient address for parallel test safety

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): use mailpit for email notification test

Replace mocked email authorization with real Mailpit verification
in the notifications.spec.ts test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): mock user response in cypress test

this broke when mailing was enabled

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-05 09:47:29 -08:00
Shaon H
8485956048 fix(web): display layers for multi-arch manifests (PROJQUAY-10020) (#4761)
When viewing a child manifest of a multi-architecture image, the Layers
tab was showing "No layers found" because manifestData was fetched for
the parent manifest list digest (which has no layers) but never
re-fetched when the user selected a specific architecture.

Fix: Make the Layers component fetch its own manifest data based on the
digest prop using a new useManifestByDigest hook. This ensures layers
are fetched for the correct child manifest digest.

Changes:
- Add useManifestByDigest hook using React Query
- Update Layers component to fetch manifest data internally
- Remove manifestData prop from Layers in TagDetailsTabs
- Add Playwright e2e tests for multi-arch manifest layers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 09:42:32 -08:00
jbpratt
ef1974688e test(web): migrate more tests to playwright (#4762)
* test(web): migrate repository-shorthand-navigation to Playwright

Migrate Cypress shorthand URL navigation tests to Playwright with real
resources instead of mocked API responses. Consolidates 11 tests into 7.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate repository-permissions to Playwright

Migrate repository-permissions.cy.ts to Playwright, consolidating
6 Cypress tests into 3 Playwright tests covering:
- Inline permission display, change, and delete operations
- Bulk permission change and delete operations
- Adding permissions for robots and teams

Changes:
- Add repository permission API utilities to client.ts
- Add api.repositoryPermission() helper with auto-cleanup
- Add data-testid attributes to PermissionsToolbar and AddPermission
- Update MIGRATION.md checklist (11 migrated, 20%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate repository-notifications to Playwright

Migrate 18 Cypress tests from repository-notifications.cy.ts to 7
consolidated Playwright tests covering notification CRUD operations,
bulk actions, and recipient field functionality.

Changes:
- Add notification API utilities to client.ts
- Add notification() method to TestApi for auto-cleanup
- Add IMAGE_EXPIRY_TRIGGER to QuayFeature type
- Add data-testid attributes to notification form components
- Create notifications.spec.ts with 7 focused tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate repositories-list to Playwright

Migrate repositories-list.cy.ts from Cypress to Playwright, consolidating
11 tests into 6 focused e2e tests:

- displays repositories in global and organization views
- creates repositories with different visibility and namespaces
- deletes multiple repositories via bulk action
- changes visibility for multiple repositories
- searches by name and supports regex mode
- searches by name including organization

Skipped pagination tests (test PatternFly, not app code).

Added data-testid attributes:
- CreateRepoModalTemplate: form inputs, visibility radios, buttons
- BulkDeleteModalTemplate: modal, confirmation input
- RepositoryToolBar: visibility confirmation buttons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate robot-accounts to Playwright

Migrate robot-accounts.cy.ts from Cypress to Playwright, consolidating
12 tests into 4 focused e2e tests:

- CRUD lifecycle: create, search, toolbar, and delete robot account
- robot credentials and Kubernetes secrets
- robot repository permissions: update single permission
- robot wizard: org has 5 steps, user namespace has 3 steps

Added data-testid attributes:
- CreateRobotAccountModal: modal container
- RobotTokensModal: regenerate button, token display, docker/podman commands
- robotAccountWizard: step navigation, name/description inputs
- ExpandCollapseButton, SearchInput, ToolbarButton: pass-through testid
- RobotAccountKebab: menu items for permissions, tokens, delete
- RobotAccountsList: table container

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): remove migrated cypress tests

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-02 13:37:05 -05:00
jbpratt
5a86c7a57f test(web): migrate some tests and improve framework (#4760)
* test(web): migrate logout Cypress test to Playwright

Uses unique temporary users per test to avoid session invalidation
conflicts when running in parallel. Quay's signout endpoint invalidates
all sessions for a user, which would break parallel tests sharing users.

Also documents the session-destructive test pattern in MIGRATION.md.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate mirroring Cypress test to Playwright

Migrates web/cypress/e2e/mirroring.cy.ts to Playwright following the
MIGRATION.md guide. Consolidates 18 Cypress tests into 5 Playwright
tests using real API calls instead of mocks.

Changes:
- Add mirroring API utilities to client.ts (changeRepositoryState,
  createMirrorConfig, getMirrorConfig, updateMirrorConfig,
  triggerMirrorSync, cancelMirrorSync)
- Create mirroring.spec.ts with 5 consolidated tests covering:
  - State warning and form visibility
  - New mirror configuration lifecycle
  - Existing mirror configuration management
  - Sync operations
  - Error handling (only mock used for 400 error scenario)
- Update MIGRATION.md checklist (8/54, 15%)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): add TestApi fixture with auto-cleanup for Playwright tests

Introduce a TestApi class that wraps ApiClient and automatically tracks
created resources for cleanup after each test. This eliminates the need
for manual beforeEach/afterEach cleanup patterns and ensures resources
are always cleaned up even when tests fail.

Changes:
- Add TestApi class to fixtures.ts with methods for creating orgs,
  repos, teams, robots, and prototypes with auto-cleanup
- Add api and superuserApi fixtures that provide TestApi instances
- Migrate all committed Playwright tests to use the new api fixture
- Update MIGRATION.md with documentation for the new pattern

The api fixture provides:
- api.organization(prefix?) - creates org with unique name
- api.repository(namespace?, prefix?, visibility?) - creates repo
- api.team(orgName, prefix?, role?) - creates team
- api.robot(orgName, prefix?, description?) - creates robot
- api.prototype(orgName, role, delegate, activatingUser?) - creates default permission
- api.setMirrorState(namespace, repoName) - sets repo to MIRROR state
- api.raw - access underlying ApiClient for non-tracked operations

Resources are cleaned up in reverse order (LIFO) after each test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): remove migrated tests

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(web): auto-skip Playwright tests based on @feature: tags

Adds an auto-fixture to fixtures.ts that automatically skips tests
when their @feature:X tags reference disabled Quay features. This
eliminates duplication between tags and manual test.skip() calls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(web): set axios baseURL at module level for all routes (PROJQUAY-0000)

Previously axios baseURL was only set inside StandaloneMain component,
causing requests from /signin and other auth routes to go to the wrong
URL (localhost:9000 instead of localhost:8080).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): use cy.session() for Cypress authentication

Replace manual CSRF token + loginByCSRF pattern with cy.session()
for proper session handling. Fixes race condition where React app
made API calls before Cypress login completed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): fix notification drawer test flakiness with toPass polling

Use Playwright's toPass to poll for notification appearance instead of
a single assertion. The backend may take time to process push
notifications, so reload and retry until the notification is visible.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-23 16:35:54 -06:00
jbpratt
05495a2995 test(web): migrate more tests to playwright (#4741)
* test(web): migrate notification-drawer Cypress test to Playwright

Convert the notification-drawer.cy.ts test from mocked API responses to
real API interactions. The test now creates a repository, configures a
quay_notification for repo_push events, pushes an image to trigger the
notification, then validates the drawer UI behavior (open, read, delete).

Adds createRepositoryNotification method to the Playwright API client.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate default-permissions Cypress test to Playwright

- Add robot and prototype API methods to test client
- Fix undefined allMembers bug in CreateTeamWizard.tsx
- Fix missing return value in AddTeamMember.tsx setDeletedTeamMembers
- Tests run in parallel with isolated state per test

Co-authored-by: Claude <noreply@anthropic.com>

* test(web): migrate external-scripts Cypress test to Playwright

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-17 18:51:53 -05:00
jbpratt
2c14bcadf5 fix(web): hide the overview route for on prem (PROJQUAY-0000) (#4737)
fix(web): hide the overview route for on prem

Signed-off-by: Brady Pratt <bpratt@redhat.com>
2025-12-16 11:09:11 -06:00
jbpratt
c52deaa6b3 test(web): migrate some cypress tests to playwright (#4734)
* test(web): migrate theme-switcher tests from Cypress to Playwright

Replace Cypress theme-switcher.cy.ts with Playwright equivalent.
Uses real API calls instead of mocked intercepts per migration guide.
Tests theme toggle visibility, persistence, and browser color scheme
detection via Playwright's emulateMedia API.

- Add data-testid to user-menu-toggle for stable selector
- Create playwright/e2e/ui/theme-switcher.spec.ts with 3 test cases
- Update MIGRATION.md checklist (2/54 migrated)
- Delete original Cypress test file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate breadcrumbs tests from Cypress to Playwright

Add organization, team, and container API utilities to support the
breadcrumbs test migration. Tests cover:
- List pages (no breadcrumbs)
- Organization, repository, tag, and team page breadcrumbs
- Edge cases with same-name org/repo/team combinations

The container utility supports both podman and docker for pushing
test images when testing tag breadcrumbs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test(web): migrate overview tests from Cypress to Playwright

Migrates web/cypress/e2e/overview.cy.ts to Playwright with 4 tests:
- Expandable dropdowns show content
- External links navigate correctly
- Tabs switch content correctly
- Purchase plans dropdown shows pricing options

Uses getByRole for tab selection instead of PatternFly-generated IDs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* test(ci): ignore test files for web preview

no need in deploying the web preview if only tests or docs are modified

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-15 18:58:23 -06:00
jbpratt
69b7aff5b4 chore: add Playwright e2e test infrastructure (#4688)
* chore: add Playwright e2e test infrastructure

Add Playwright test framework with custom fixtures for authenticated
contexts, API utilities for test data management, and repository
delete test as initial migration from Cypress.

Key additions:
- global-setup.ts: Creates admin, testuser, readonly test users
- fixtures.ts: Pre-authenticated page/request fixtures by role
- utils/api.ts: CRUD utilities for repositories
- MIGRATION.md: Guide for migrating Cypress tests to Playwright
- repository-delete.spec.ts: First migrated test with full cleanup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Brady Pratt <bpratt@redhat.com>

* chore: update web/.dockerignore

exclude tests from being included in the intermediate build - this
should improve caching when only tests change

Signed-off-by: Brady Pratt <bpratt@redhat.com>

* chore: add pre-commit check to block new cypress tests

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-12 18:40:38 -06:00
Harish Govindarajulu
5a0d7efecd fix(ui): add label to show global readonly superuser in organizations list (PROJQUAY-9970) (#4717)
This commit adds a cyan "Global Readonly Superuser" label to identify
global readonly superusers in the Organizations list, making it easier
for administrators to distinguish them from regular superusers.

Backend change: Updated User.to_dict() to include global_readonly_super_user
property in the /api/v1/superuser/users/ API response.

Frontend changes: Propagated the property through the data flow and added
label rendering with cyan color to visually distinguish from regular
superusers (blue).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 14:44:28 -06:00
jbpratt
8593006231 fix(web): sort Build ID column numerically as hex values (PROJQUAY-9895) (#4701)
Build IDs are UUIDs displayed as hex strings. The previous localeCompare
sorting treated them lexicographically, causing incorrect sort order.
Now detects hex/UUID patterns and sorts by parsing the first 8 hex
digits numerically.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-10 04:26:51 -06:00
jbpratt
ced2c6ffa8 feat(endpoints,web): add audit logs for quota configuration (PROJQUAY-9859) (#4692)
Adds audit logging for all quota management operations:
- org_create_quota, org_change_quota, org_delete_quota
- org_create_quota_limit, org_change_quota_limit, org_delete_quota_limit

Backend changes:
- Add LogEntryKind types in initdb.py
- Add log_action calls in namespacequota.py endpoints
- Add Alembic migration for new log kinds
- Add unit tests for audit logging

Frontend changes:
- Add log descriptions in UseLogDescriptions.tsx
- Add Cypress e2e test for quota log display

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 09:44:10 -06:00
jbpratt
d04f98dbcd fix(web): use template literals for Fetch Tag pull commands (PROJQUAY-9952) (#4699)
ClipboardCopy children were passed as JSX expressions which creates an
array of React nodes. PatternFly's ClipboardCopy may join array children
with commas when extracting text, causing pull commands like:
"docker pull ,hostname,/,org,/,repo,:,tag"

Using template literals ensures a single string child is passed,
preventing the comma issue.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-09 17:29:43 +05:30
jbpratt
63bb7af32b fix(web): show error notification on org creation failure (PROJQUAY-9948) (#4691)
Use mutateAsync instead of mutate so Promise errors propagate to the
calling code. Previously, mutate() was fire-and-forget, causing success
notifications even when the API returned 400 errors.

Remove duplicate alert notification - error is shown inline in the modal.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-08 16:58:35 +05:30
jbpratt
f4957e3e29 chore: remove deprecated reCAPTCHA support (#4690)
Remove reCAPTCHA integration from the password recovery flow
as the feature has been deprecated.

Changes:
- Delete ReCaptcha component
- Remove recaptcha token handling from Signin page
- Simplify UsePasswordRecovery hook
- Remove react-google-recaptcha dependencies
- Clean up test fixtures and CSS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 08:10:43 -06:00
jbpratt
c6d948e11b fix(web): display 0.00 KiB instead of N/A for zero sizes (PROJQUAY-9860) (#4686)
The formatSize() function used a falsy check which treated 0 as invalid,
returning "N/A" instead of formatting it. Now 0 displays as "0.00 KiB"
matching the legacy UI behavior.

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 19:44:53 +00:00
jbpratt
ed6ebc3ff6 feat(web): show password setup prompt for OIDC users in CLI config (PROJQUAY-9898) (#4681)
when using OIDC authentication and the user has no password set, display
an info alert with a "Set password" button to guide users through setting
up their CLI password

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 19:05:24 +00:00
Sunandadadi
acfbf1cb6d fix(web): enable user self-service email changes when FEATURE_MAILING enabled (PROJQUAY-9879) (#4675)
* fix(web): enable user self-service email changes when FEATURE_MAILING enabled (PROJQUAY-9879)

This commit fixes the issue where users received 401 Unauthorized errors
when attempting to update their email address in the new React UI when
FEATURE_MAILING is enabled.

Root cause: ChangeEmailModal was using the superuser-only endpoint
/api/v1/superuser/users/{username}, which regular users cannot access.

Changes:
- Added useChangeEmail hook in UseCurrentUser.ts that calls the correct
  user self-service endpoint /api/v1/user/ for email updates
- Modified ChangeEmailModal to support dual modes (superuser vs user)
  with isSuperuserMode prop for backward compatibility
- Updated GeneralSettings to display email as clickable link when
  FEATURE_MAILING is enabled, opening the modal for email changes
- Pre-fill modal with current email address for better UX
- Added validation to prevent submitting the same email address
- Added 8 comprehensive Cypress e2e tests covering email change flows

The fix implements the proper email verification workflow where users
receive a verification email and must confirm before the change is applied.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fixing tests

* resolving coderabbit suggestion

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-03 16:07:53 +00:00
jbpratt
365f88cf0b chore: remove debug css (#4669)
Signed-off-by: Brady Pratt <bpratt@redhat.com>
2025-12-02 15:16:36 +00:00
jbpratt
9337b87f0e fix(web): disable buttons for global readonly superuser (PROJQUAY-9873) (#4665)
Global readonly superusers could click Create Message and Service Key
buttons which then failed with 403 errors. These buttons are now disabled
using the existing useSuperuserPermissions hook's canModify flag.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-02 08:22:56 -06:00
jbpratt
754196f9ac fix(web): use correct terminology in user settings panel (PROJQUAY-9884) (#4659)
The settings page showed "Organization" labels and helper text even
when viewing a user namespace. Changed to conditionally display
"Username" for users and "Organization" for organizations.

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 11:38:48 -06:00
jbpratt
0b8e74f5ac fix(web): resolve user settings log display issues (PROJQUAY-9881) (#4657)
fix(web): fix user settings log display issues (PROJQUAY-9881)

- Fix template interpolation in user_change_tag_expiration log message
- Add usageLogs query invalidation so logs refresh after settings update

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 17:21:04 +00:00
jbpratt
72d1e4f398 fix(web): show user namespace quota for non-superusers (PROJQUAY-9886) (#4658)
Normal users couldn't see their own namespace quota in the Organizations
list Size column. The backend already returns quota_report in /api/v1/user/
but the frontend wasn't using it. Added fallback to use current user's
quota_report when superuser data isn't available.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 11:11:26 -06:00
jbpratt
6bc089b61c fix(web): use correct error modal titles for different operations (PROJQUAY-9874) (#4655)
Previously, all errors on the Organizations page showed "Org deletion failed"
as the modal title, even for unrelated operations like registry size
calculation. This was confusing for Global Readonly Superusers who saw
"Org deletion failed" when trying to calculate registry size.

Changes:
- Separated error states in OrganizationsList.tsx (deletionErr, registryCalcErr)
- Added separate ErrorModal for registry calculation with correct title
- Fixed RepositoriesList.tsx ErrorModal title to "Repository deletion failed"
- Added Cypress test to verify correct error modal title

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 10:22:48 -06:00
jbpratt
37ca1eaf2d fix(web): hide Enable Team Sync when FEATURE_TEAM_SYNCING is false (PROJQUAY-9878) (#4654)
The UI was showing the "Enable OIDC Team Sync" button even when
FEATURE_TEAM_SYNCING was disabled in the config. Added check for
config?.features?.TEAM_SYNCING before displaying the team sync button.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 08:38:16 -06:00
Sunandadadi
e7988418f9 ui: ensure logout redirects to signin on network error (PROJQUAY-9792) (#4652)
fix(ui): ensure logout redirects to signin on network error (PROJQUAY-9792)

When the logout API call fails due to network error, the UI now properly
redirects to the signin page and clears the client-side session. Previously,
the user would be stuck on the current page with an error modal.

Changes:
- Move redirect and cleanup to finally block in logout handler
- Add optional chaining to user.username to prevent undefined errors
- Remove unused addDisplayError import
- Add comprehensive Cypress e2e tests for logout functionality

The finally block ensures client-side logout always succeeds, even when
the server is unreachable, improving security and user experience.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-01 03:18:36 -06:00
jbpratt
cdd8259c14 fix(web): load external scripts only when BILLING enabled (PROJQUAY-9803) (#4623)
Stripe and StatusPage scripts were hardcoded in index.html, causing
85-second delays in air-gapped/restricted networks as browsers waited
for connection timeouts.

Created useExternalScripts hook to dynamically load scripts only when
BILLING feature is enabled. Scripts load asynchronously to prevent
blocking page render. On-premise deployments (BILLING=false) no longer
make external requests.

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 22:55:10 +00:00
Brandon Caton
f57ac3f67f ui: checking field content in superuser build logs (PROJQUAY-9714) (#4640) 2025-11-25 15:19:16 -05:00
Harish Govindarajulu
36dff40df7 fix(ui): show quota consumed column for all users in organizations list (PROJQUAY-9850) (#4634)
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 19:37:21 +05:30
jbpratt
79f75e24b6 fix(web): display avatars for all entries in org table (PROJQUAY-9749) (#4615)
Previously only organizations and the logged-in user showed avatars.
Now all users and superusers display avatars by passing avatar data
from the API response through component props.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 19:36:41 +05:30
jbpratt
b4f1ef63c6 fix(web): hide Add Limit form in view-only quota pages (PROJQUAY-9845) (#4622)
Organization and user quota settings pages are view-only, but were
displaying an empty "Add Limit" form row with disabled controls.
This creates visual clutter and implies users can add limits when
they cannot.

Conditionally render the "Add Limit" card only when !isReadOnly to
match the behavior of the old Angular UI. Update Cypress tests to
verify the form does not exist (not just disabled) in view-only mode.
2025-11-25 04:17:23 -06:00
Sunandadadi
40ee3a5468 ui: prevent redirect to signin after OIDC username confirmation (PROJQUAY-9835) (#4629)
fix(web): prevent redirect to signin after OIDC username confirmation (PROJQUAY-9835)

When users authenticated via OIDC and confirmed their username, they were
incorrectly redirected back to the signin page instead of the home page.

This occurred because the OAuth flow stored the signin page URL in localStorage
as the redirect target. After username confirmation, the app would read this
stored URL and redirect back to signin, creating a loop.

The fix checks if the stored redirect URL contains '/signin' and navigates to
the home page instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 21:35:55 +00:00
Brandon Caton
4cddc368e9 ui: surfacing re-prompt for password (PROJQUAY-9844) (#4624) 2025-11-24 21:25:41 +00:00
Brandon Caton
b2141c1d60 ui: fix select during org delete bug (PROJQUAY-9843) (#4628) 2025-11-24 16:13:20 -05:00
jbpratt
f5db7ddb5b fix(web): sort Build History by timestamp instead of string (PROJQUAY-9686) (#4619)
Converts date strings to numeric timestamps for correct chronological sorting
2025-11-24 12:17:49 -06:00
jbpratt
b352135a85 fix(web): validate quota value input accepts only numbers (PROJQUAY-9837) (#4614)
* fix(web): validate quota value input accepts only numbers (PROJQUAY-9837)

Changed Storage Quota input from type="text" to type="number" to prevent
non-numeric characters from being entered. Also enhanced validation to
catch edge cases where parseFloat could incorrectly parse mixed values
like "300xxxx" as 300.

Co-authored-by: Claude <noreply@anthropic.com>

* chore: move quota test seeding

locally the test goes from 8 minutes to 55 seconds :)

Signed-off-by: Brady Pratt <bpratt@redhat.com>

---------

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 13:04:38 -05:00
jbpratt
bb31def220 chore: fix account settings navigation (#4607)
don't reload the page, use react router to navigate smoothly

Signed-off-by: Brady Pratt <bpratt@redhat.com>
2025-11-24 10:46:15 +05:30
jbpratt
9d0e3d29bc fix(ui): preserve mirroring credentials when updating tag pattern (PROJQUAY-9608) (#4410)
When updating mirroring configuration fields like tag patterns, credentials
were being cleared because the password field is empty by default for security.

Modified UseMirroringConfig to conditionally exclude credentials from the
update payload when the password field is empty and updating existing config.
This matches the Angular UI behavior where only changed fields are sent.

Added Cypress tests to verify credentials are preserved when updating other
fields without changing the password, and that credentials are included when
explicitly updated.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Brady Pratt <bpratt@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-20 22:57:36 +00:00