Skip to content

Align LibreSign with @nextcloud/vue 9.13 and harden the related E2E coverage #8704

Closed

Description

@vitormattos

Context

Dependabot PR #8609 updates @nextcloud/vue from 9.12.0 to 9.13.0. The JavaScript build, TypeScript check, ESLint, stylelint and Node/Vitest jobs pass, but the Playwright E2E job fails.

This issue is intentionally broader than “make the failing Playwright test green”: the goal is to make the LibreSign frontend correctly consume the public contracts of @nextcloud/vue 9.13.x, remove compatibility shims that hide type problems, and make the E2E failure diagnosable instead of producing cascaded errors.

Related:

What was observed

On PR #8609:

  • build: passes
  • vue-tsc --noEmit: passes
  • ESLint/stylelint: pass
  • Node/Vitest tests: pass
  • Playwright: fails

The first relevant Playwright failure is:

playwright/e2e/observer-participant-flow.spec.ts
→ email observer receives validation link when the signer uses account identification

The Playwright failure artifact shows the “Upload from URL” dialog with the URL visibly filled but the Send button still disabled. The test then does not advance through the normal upload flow. Cleanup subsequently fails with ECONNREFUSED against localhost:8080, and the following tests mostly fail for the same reason. Those later errors are cascading failures and must not be treated as independent regressions.

The PHP built-in server log ends with an accepted connection and no matching response/close entry. There is no useful PHP fatal error in the captured log, so the current workflow does not preserve enough information to determine why the server disappears.

Important: NcTextField is not among the files changed upstream between @nextcloud/vue 9.12.0 and 9.13.0. Do not assume that its v-model contract changed.

Relevant upstream changes in @nextcloud/vue 9.13.0

The 9.13.0 release includes:

  • NcModal: slideshow state exposed as a model
  • NcAvatar: new version prop
  • NcAppNavigation: fixes navigation-toggled emission on mobile changes
  • dialog mobile selector specificity fix
  • NcAppContent*: migrated to TypeScript
  • NcAppContent*: migrated to <script setup>
  • @nextcloud/files dependency/peer alignment to 4.1.0
  • dependency and translation updates

For LibreSign, the highest-risk areas are therefore the app layout/navigation/dialog integration and the fact that the package now exposes stronger TypeScript types.

Existing LibreSign technical debt found during the audit

1. Remove the wildcard @nextcloud/vue type shim

src/env.d.ts currently contains:

declare module '@nextcloud/vue/components/*' {
    import type { DefineComponent } from 'vue'
    const component: DefineComponent
    export default component
}

This turns all @nextcloud/vue components into essentially untyped generic Vue components and can hide invalid props/events/models from vue-tsc.

Remove this declaration and fix every real TypeScript error exposed by the package's own declarations. Do not replace it with another wildcard declaration.

2. Audit NcAppContent/NcContent usage against the public API

LibreSign currently has a root NcAppContent in src/App.vue, while views such as src/views/FilesList/FilesList.vue create another NcAppContent.

Verify the intended Nextcloud layout hierarchy and avoid nested NcAppContent instances unless the upstream component contract explicitly supports that structure.

Also audit CSS that reaches into implementation classes such as:

  • .app-content
  • .app-navigation
  • .app-navigation-entry

Prefer LibreSign-owned classes, documented slots/props, or public Nextcloud CSS contracts. Do not depend on private DOM structure merely to keep the current appearance.

3. Verify the @nextcloud/files floor

@nextcloud/vue 9.13.0 expects the stable @nextcloud/files 4.1.x peer contract. LibreSign's manifest currently declares @nextcloud/files: ^4.0.0.

Check the actual lockfile resolution. If the installed top-level package is already 4.1.x, update the direct dependency floor to ^4.1.0 so the manifest documents the real compatibility requirement. If it is not 4.1.x, update it and regenerate the lockfile.

Do not hand-edit package-lock.json.

4. Audit actual deprecated API usage, but do not perform unrelated churn

Search LibreSign usages of @nextcloud/vue against the 9.13.0 source/type declarations.

Only migrate APIs that are actually deprecated or incompatible.

For example, NcCheckboxRadioSwitch has deprecated button-variant/grouping APIs in favor of NcRadioGroup, but normal checkbox/switch usage is not automatically a reason to rewrite every occurrence. Keep this PR scoped to documented deprecations that LibreSign is actually using.

5. Add a regression test for the URL upload dialog using the real Nextcloud Vue contract

The existing unit tests/stubs are not sufficient to detect the E2E state observed in #8609.

Add a focused regression test around RequestPicker.vue that verifies:

  1. open “Upload from URL”
  2. enter a syntactically valid URL
  3. the Send action becomes enabled
  4. submit invokes the upload path once
  5. an invalid/empty URL keeps Send disabled

Prefer mounting enough of the real NcTextField/NcDialog behavior to exercise the model/event contract. If a component must be stubbed, the stub must accurately implement the production modelValue + update:modelValue contract.

Do not “fix” the E2E by forcing a click on a disabled button.

6. Make the Playwright web server failure fail fast and preserve the primary error

The current failure produces many misleading ECONNREFUSED errors after the first test stops progressing.

Improve the E2E harness/workflow so that:

  • the PHP server PID is checked while/after a failed test;
  • if the server died, its exit condition and the last useful log lines are printed;
  • cleanup errors do not hide the original Playwright assertion/action timeout;
  • subsequent tests are not reported as separate application regressions after the shared server is gone;
  • diagnostics remain available as workflow artifacts.

Do not solve this with retries alone.

Required investigation before changing production code

Run the first failing scenario in isolation on both dependency states:

  1. @nextcloud/vue 9.12.0
  2. @nextcloud/vue 9.13.0

Use the same Nextcloud server revision/environment when comparing them.

Record whether the isolated test reproduces on each version.

Then determine the first divergent observable state. At minimum inspect:

  • pdfUrl / the field model after filling the URL;
  • canUploadFronUrl;
  • enabled/disabled state of Send;
  • browser console errors;
  • uncaught page errors;
  • network requests immediately before the timeout;
  • PHP server PID/status and last log entries.

If 9.12.0 fails under the same environment, treat this as an existing/flaky LibreSign E2E bug exposed by the Dependabot PR rather than claiming a 9.13.0 regression.

If only 9.13.0 fails, identify the specific upstream contract/change responsible before adding a workaround.

Implementation constraints

  • Do not pin back to 9.12.0 as the final solution.
  • Do not add sleeps or arbitrary timeouts.
  • Do not weaken Playwright assertions just to make CI green.
  • Do not add another ambient wildcard declaration for @nextcloud/vue.
  • Do not depend on undocumented internal DOM/class names when a public component API can be used.
  • Keep dependency changes reproducible through npm and commit the regenerated lockfile.
  • Keep user-visible behavior unchanged unless an upstream public API requires a deliberate migration.

Validation

Before opening the PR, run at least:

npm ci
npm run build
npm run ts:check
npm run lint
npm run stylelint
npm test
npm run test:e2e -- playwright/e2e/observer-participant-flow.spec.ts
npm run test:e2e

If the repository's E2E wrapper expects a different argument form, use the equivalent project command; do not bypass the repository setup.

Also verify the CI jobs that passed before this issue remain green.

Acceptance criteria

  • @nextcloud/vue 9.13.x is kept and installs reproducibly.
  • The wildcard @nextcloud/vue/components/* declaration is removed from src/env.d.ts.
  • Any real TypeScript errors exposed by removing the shim are fixed using upstream types/public APIs.
  • @nextcloud/files is aligned/documented at the actual compatible 4.1.x floor when required by the resolved dependency graph.
  • NcContent/NcAppContent hierarchy is checked and corrected where it violates the upstream component contract.
  • LibreSign no longer relies on avoidable private NcAppContent/navigation DOM classes in the touched area.
  • The URL upload dialog has a regression test covering the enabled/disabled Send state and submission.
  • The originally failing Playwright scenario passes in isolation.
  • The full Playwright suite passes without cascading ECONNREFUSED failures.
  • When the shared PHP test server exits unexpectedly, CI surfaces the server failure and preserves the primary test error.
  • build, type check, ESLint, stylelint and Node/Vitest tests pass.
  • The PR description records whether the problem reproduced on 9.12.0 and 9.13.0 and states the proven root cause rather than only the symptom.

Notes for contributors

A good solution should make the dependency update boring: public APIs and types should catch compatibility issues before E2E, and an E2E infrastructure failure should point directly to its primary cause.

When using an AI coding assistant, give it this issue plus the upstream @nextcloud/vue 9.13.0 changelog and require it to cite the exact upstream component/type contract before changing LibreSign code. Review generated changes normally; do not accept speculative compatibility workarounds.

Activity

  1. paulo-raoni commented on Sep 25, 2026

    @paulo-raoni
    Contributor

    Hi! I'd like to take this one.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

Priority

None yet

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions