diff --git a/changelog/unreleased/enhancement-add-not-found-page b/changelog/unreleased/enhancement-add-not-found-page
new file mode 100644
index 00000000000..66ac9783ced
--- /dev/null
+++ b/changelog/unreleased/enhancement-add-not-found-page
@@ -0,0 +1,6 @@
+Enhancement: Add not found page
+
+We've added a not found page to communicate to users when they've navigated to a page that doesn't exist.
+
+https://github.com/owncloud/web/pull/11737
+https://github.com/owncloud/web/issues/5804
diff --git a/packages/web-runtime/src/pages/notFound.vue b/packages/web-runtime/src/pages/notFound.vue
new file mode 100644
index 00000000000..b97901ecfa8
--- /dev/null
+++ b/packages/web-runtime/src/pages/notFound.vue
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/packages/web-runtime/src/router/index.ts b/packages/web-runtime/src/router/index.ts
index 7fc6f73def8..46c66ef63c1 100644
--- a/packages/web-runtime/src/router/index.ts
+++ b/packages/web-runtime/src/router/index.ts
@@ -2,6 +2,7 @@ import AccessDeniedPage from '../pages/accessDenied.vue'
import Account from '../pages/account.vue'
import LoginPage from '../pages/login.vue'
import LogoutPage from '../pages/logout.vue'
+import NotFoundPage from '../pages/notFound.vue'
import OidcCallbackPage from '../pages/oidcCallback.vue'
import ResolvePublicLinkPage from '../pages/resolvePublicLink.vue'
import ResolvePrivateLinkPage from '../pages/resolvePrivateLink.vue'
@@ -86,6 +87,12 @@ const routes = [
name: 'account',
component: Account,
meta: { title: $gettext('Account'), authContext: 'hybrid' }
+ },
+ {
+ path: '/:pathMatch(.*)*',
+ name: 'notFound',
+ component: NotFoundPage,
+ meta: { title: $gettext('Not found'), authContext: 'hybrid' }
}
]
export const router = patchRouter(
diff --git a/tests/e2e/cucumber/features/navigation/pageNotFoud.feature b/tests/e2e/cucumber/features/navigation/pageNotFoud.feature
new file mode 100644
index 00000000000..eaae133c947
--- /dev/null
+++ b/tests/e2e/cucumber/features/navigation/pageNotFoud.feature
@@ -0,0 +1,13 @@
+Feature: Page not found
+ As a user
+ I want to see a not found page
+ So that I know when I've navigated to a page that doesn't exist
+
+ Scenario: not found page
+ Given "Admin" creates following user using API
+ | id |
+ | Alice |
+ And "Alice" logs in
+ When "Alice" navigates to a non-existing page
+ Then "Alice" should see the not found page
+ And "Alice" logs out
diff --git a/tests/e2e/cucumber/steps/ui/navigateByUrl.ts b/tests/e2e/cucumber/steps/ui/navigateByUrl.ts
index 84a06a5cdd1..aa7e066e421 100644
--- a/tests/e2e/cucumber/steps/ui/navigateByUrl.ts
+++ b/tests/e2e/cucumber/steps/ui/navigateByUrl.ts
@@ -1,4 +1,4 @@
-import { When } from '@cucumber/cucumber'
+import { Then, When } from '@cucumber/cucumber'
import { World } from '../../environment'
import { objects } from '../../../support'
@@ -54,3 +54,21 @@ When(
await urlNavObject.openSpaceViaUrl({ user, space })
}
)
+
+When(
+ '{string} navigates to a non-existing page',
+ async function (this: World, stepUser: string): Promise {
+ const { page } = this.actorsEnvironment.getActor({ key: stepUser })
+ const urlNavObject = new objects.urlNavigation.URLNavigation({ page })
+ await urlNavObject.navigateToNonExistingPage()
+ }
+)
+
+Then(
+ '{string} should see the not found page',
+ async function (this: World, stepUser: string): Promise {
+ const { page } = this.actorsEnvironment.getActor({ key: stepUser })
+ const urlNavObject = new objects.urlNavigation.URLNavigation({ page })
+ await urlNavObject.waitForNotFoundPageToBeVisible()
+ }
+)
diff --git a/tests/e2e/support/objects/url-navigation/actions.ts b/tests/e2e/support/objects/url-navigation/actions.ts
index 6ae5cdaac07..689f55fc335 100644
--- a/tests/e2e/support/objects/url-navigation/actions.ts
+++ b/tests/e2e/support/objects/url-navigation/actions.ts
@@ -86,3 +86,10 @@ const getTheFileIdOfSpaceFile = async (
spaceName
})
}
+
+export const navigateToNonExistingPage = async ({ page }: { page: Page }) => {
+ await page.goto(`${config.backendUrl}/'a-non-existing-page'`)
+}
+export const waitForNotFoundPageToBeVisible = async ({ page }: { page: Page }) => {
+ await page.locator('.page-not-found').waitFor()
+}
diff --git a/tests/e2e/support/objects/url-navigation/index.ts b/tests/e2e/support/objects/url-navigation/index.ts
index 02ff132c308..cf28501f2a0 100644
--- a/tests/e2e/support/objects/url-navigation/index.ts
+++ b/tests/e2e/support/objects/url-navigation/index.ts
@@ -21,4 +21,11 @@ export class URLNavigation {
async openSpaceViaUrl(args: Omit): Promise {
await po.openSpaceViaUrl({ ...args, page: this.#page })
}
+
+ async navigateToNonExistingPage(): Promise {
+ await po.navigateToNonExistingPage({ page: this.#page })
+ }
+ async waitForNotFoundPageToBeVisible(): Promise {
+ await po.waitForNotFoundPageToBeVisible({ page: this.#page })
+ }
}