Skip to content

Commit f52c40f

Browse files
committed
test: replace cucumber with playwright for internalLink.feature
Signed-off-by: Ashim Shrestha <[email protected]>
1 parent b8e01de commit f52c40f

File tree

12 files changed

+507
-2
lines changed

12 files changed

+507
-2
lines changed

.drone.star

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,10 @@ def stagePipelines(ctx):
223223
if (determineReleasePackage(ctx) != None):
224224
return unit_test_pipelines
225225

226+
e2e_playwright_pipeline = e2eTestsOnPlaywright(ctx)
226227
e2e_pipelines = e2eTests(ctx)
227228
keycloak_pipelines = e2eTestsOnKeycloak(ctx)
228-
return unit_test_pipelines + pipelinesDependsOn(e2e_pipelines + keycloak_pipelines, unit_test_pipelines)
229+
return unit_test_pipelines + pipelinesDependsOn(e2e_playwright_pipeline + e2e_pipelines + keycloak_pipelines, unit_test_pipelines)
229230

230231
def afterPipelines(ctx):
231232
return build(ctx) + pipelinesDependsOn(notify(ctx), build(ctx))
@@ -535,6 +536,64 @@ def unitTests(ctx):
535536
},
536537
}]
537538

539+
def e2eTestsOnPlaywright(ctx):
540+
e2e_workspace = {
541+
"base": dir["base"],
542+
"path": config["app"],
543+
}
544+
545+
e2e_trigger = {
546+
"ref": [
547+
"refs/heads/master",
548+
"refs/heads/stable-*",
549+
"refs/tags/**",
550+
"refs/pull/**",
551+
],
552+
}
553+
554+
pipelines = []
555+
556+
# pipeline steps
557+
steps = skipIfUnchanged(ctx, "e2e-tests-playwright")
558+
559+
environment = {
560+
"BASE_URL_OCIS": "ocis:9200",
561+
"PLAYWRIGHT_BROWSERS_PATH": ".playwright",
562+
}
563+
564+
steps += restoreBuildArtifactCache(ctx, "pnpm", ".pnpm-store") + \
565+
installPnpm() + \
566+
restoreBrowsersCache() + \
567+
restoreBuildArtifactCache(ctx, "web-dist", "dist")
568+
569+
if ctx.build.event == "cron":
570+
steps += restoreBuildArtifactCache(ctx, "ocis", "ocis")
571+
else:
572+
steps += restoreOcisCache()
573+
574+
steps += ocisService()
575+
576+
steps += [{
577+
"name": "e2e-tests-playwright",
578+
"image": OC_CI_NODEJS_IMAGE,
579+
"environment": environment,
580+
"commands": [
581+
"pnpm test:e2e:playwright --project=chromium",
582+
],
583+
}]
584+
585+
pipelines.append({
586+
"kind": "pipeline",
587+
"type": "docker",
588+
"name": "e2e-tests-playwright",
589+
"workspace": e2e_workspace,
590+
"steps": steps,
591+
"depends_on": ["cache-ocis"],
592+
"trigger": e2e_trigger,
593+
})
594+
595+
return pipelines
596+
538597
def e2eTests(ctx):
539598
e2e_workspace = {
540599
"base": dir["base"],
@@ -1365,12 +1424,26 @@ def skipIfUnchanged(ctx, type):
13651424
}
13661425
return [skip_step]
13671426

1427+
if type == "e2e-tests-playwright":
1428+
e2e_playwright_skip_steps = [
1429+
"^__fixtures__/.*",
1430+
"^__mocks__/.*",
1431+
"^packages/.*/tests/.*",
1432+
"^tests/unit/.*",
1433+
"^tests/e2e/.*",
1434+
]
1435+
skip_step["settings"] = {
1436+
"ALLOW_SKIP_CHANGED": base_skip_steps + e2e_playwright_skip_steps,
1437+
}
1438+
return [skip_step]
1439+
13681440
if type == "e2e-tests":
13691441
e2e_skip_steps = [
13701442
"^__fixtures__/.*",
13711443
"^__mocks__/.*",
13721444
"^packages/.*/tests/.*",
13731445
"^tests/unit/.*",
1446+
"^tests/e2e-playwright/.*",
13741447
]
13751448
skip_step["settings"] = {
13761449
"ALLOW_SKIP_CHANGED": base_skip_steps + e2e_skip_steps,

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"lint": "eslint vite.config.ts '{packages,tests}/**/*.{js,ts,vue}' --color",
1313
"serve": "SERVER=true pnpm build:w",
1414
"test:e2e:cucumber": "NODE_TLS_REJECT_UNAUTHORIZED=0 TS_NODE_PROJECT=./tests/e2e/cucumber/tsconfig.json cucumber-js --profile=e2e -f json:tests/e2e/cucumber/report/cucumber_report.json",
15+
"test:e2e:playwright": "NODE_TLS_REJECT_UNAUTHORIZED=0 npx playwright test --config=tests/e2e-playwright/",
1516
"test:unit": "NODE_OPTIONS=--unhandled-rejections=throw vitest",
1617
"licenses:check": "license-checker-rseidelsohn --summary --relativeLicensePath --onlyAllow 'Python-2.0;Apache*;Apache License, Version 2.0;Apache-2.0;Apache 2.0;Artistic-2.0;BSD;BSD-3-Clause;CC-BY-3.0;CC-BY-4.0;CC0-1.0;ISC;MIT;MPL-2.0;Public Domain;Unicode-TOU;Unlicense;WTFPL;BlueOak-1.0.0' --excludePackages '@ownclouders/babel-preset;@ownclouders/eslint-config;@ownclouders/prettier-config;@ownclouders/tsconfig;@ownclouders/web-client;@ownclouders/web-pkg;external;web-app-files;text-editor;preview;web-app-ocm;@ownclouders/design-system;pdf-viewer;web-app-search;admin-settings;webfinger;web-runtime;@ownclouders/web-test-helpers'",
1718
"licenses:csv": "license-checker-rseidelsohn --relativeLicensePath --csv --out ./third-party-licenses/third-party-licenses.csv",

test-results/.last-run.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"status": "passed",
3+
"failedTests": []
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { config } from '../../e2e/config.js'
2+
import { api } from '../../e2e/support'
3+
import { UsersEnvironment } from '../../e2e/support/environment'
4+
5+
export async function setAccessAndRefreshToken(usersEnvironment: UsersEnvironment) {
6+
if (!config.basicAuth && !config.predefinedUsers) {
7+
let user = usersEnvironment.getUser({ key: config.adminUsername })
8+
await api.token.setAccessAndRefreshToken(user)
9+
}
10+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { defineConfig, devices } from '@playwright/test'
2+
3+
/**
4+
* See https://playwright.dev/docs/test-configuration.
5+
*/
6+
export default defineConfig({
7+
// Look for test files in the "tests" directory, relative to this configuration file.
8+
testDir: 'specs',
9+
10+
// Run all tests in parallel.
11+
fullyParallel: false,
12+
13+
// Fail the build on CI if you accidentally left test.only in the source code.
14+
forbidOnly: !!process.env.CI,
15+
16+
// Retry on CI only.
17+
retries: process.env.CI ? 1 : 0,
18+
19+
// Opt out of parallel tests on CI.
20+
workers: process.env.CI ? 1 : undefined,
21+
22+
// Reporter to use
23+
reporter: 'html',
24+
25+
use: {
26+
ignoreHTTPSErrors: true,
27+
28+
// Collect trace when retrying the failed test.
29+
trace: 'on-first-retry'
30+
},
31+
// Configure projects for major browsers.
32+
projects: [
33+
{
34+
name: 'chromium',
35+
use: { ...devices['Desktop Chrome'] }
36+
},
37+
{
38+
name: 'firefox',
39+
use: { ...devices['Desktop Firefox'] }
40+
},
41+
{
42+
name: 'webkit',
43+
use: { ...devices['Desktop Safari'] }
44+
}
45+
]
46+
})
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { expect, test } from '@playwright/test'
2+
import { config } from '../../e2e/config.js'
3+
import {
4+
ActorsEnvironment,
5+
UsersEnvironment,
6+
LinksEnvironment,
7+
FilesEnvironment
8+
} from '../../e2e/support/environment'
9+
import {
10+
userHasBeenCreated,
11+
userHasCreatedFolder,
12+
userHasSharedResource,
13+
userHasCreatedPublicLinkOfResource
14+
} from '../steps/api/api'
15+
import { setAccessAndRefreshToken } from '../helpers/setAccessAndRefreshToken'
16+
import { openPublicLink } from '../steps/ui/public'
17+
import { navigateToSharedWithMePage, updateShareeRole } from '../steps/ui/shares'
18+
import { uploadResource, isAbleToEditFileOrFolder } from '../steps/ui/resources'
19+
import { LogInUser, LogOutUser } from '../steps/ui/session'
20+
21+
test.describe('internal link share', () => {
22+
let actorsEnvironment
23+
const usersEnvironment = new UsersEnvironment()
24+
const linksEnvironment = new LinksEnvironment()
25+
const filesEnvironment = new FilesEnvironment()
26+
27+
test.beforeEach(async ({ browser }) => {
28+
actorsEnvironment = new ActorsEnvironment({
29+
context: {
30+
acceptDownloads: config.acceptDownloads,
31+
reportDir: config.reportDir,
32+
tracingReportDir: config.tracingReportDir,
33+
reportHar: config.reportHar,
34+
reportTracing: config.reportTracing,
35+
reportVideo: config.reportVideo,
36+
failOnUncaughtConsoleError: config.failOnUncaughtConsoleError
37+
},
38+
browser: browser
39+
})
40+
41+
await setAccessAndRefreshToken(usersEnvironment)
42+
43+
await userHasBeenCreated(usersEnvironment, 'Admin', 'Alice')
44+
await userHasBeenCreated(usersEnvironment, 'Admin', 'Brian')
45+
46+
await LogInUser(usersEnvironment, actorsEnvironment, 'Alice')
47+
await LogInUser(usersEnvironment, actorsEnvironment, 'Brian')
48+
49+
await userHasCreatedFolder(usersEnvironment, 'Alice', 'myfolder')
50+
51+
await userHasSharedResource(
52+
usersEnvironment,
53+
'Alice',
54+
'myfolder',
55+
'Brian',
56+
'user',
57+
'Can edit',
58+
'folder'
59+
)
60+
61+
await userHasCreatedPublicLinkOfResource(
62+
usersEnvironment,
63+
'Alice',
64+
'myfolder',
65+
'Invited people'
66+
)
67+
})
68+
69+
test('opening a link with internal role', async () => {
70+
await openPublicLink(actorsEnvironment, linksEnvironment, 'Brian', 'Unnamed link')
71+
await navigateToSharedWithMePage(actorsEnvironment, 'Brian')
72+
await uploadResource(actorsEnvironment, filesEnvironment, 'Brian', 'simple.pdf', 'myfolder')
73+
await updateShareeRole(
74+
usersEnvironment,
75+
actorsEnvironment,
76+
'Alice',
77+
'myfolder',
78+
'Brian',
79+
'user',
80+
'Can view',
81+
'folder'
82+
)
83+
await LogOutUser(actorsEnvironment, 'Alice')
84+
85+
expect(await isAbleToEditFileOrFolder(actorsEnvironment, 'Brian', 'myfolder')).toBeFalsy()
86+
await LogOutUser(actorsEnvironment, 'Brian')
87+
})
88+
})
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { config } from '../../../e2e/config.js'
2+
import { UsersEnvironment } from '../../../e2e/support/environment'
3+
import { api } from '../../../e2e/support'
4+
import { ResourceType } from '../../../e2e/support/api/share/share'
5+
6+
export async function userHasBeenCreated(
7+
usersEnvironment: UsersEnvironment,
8+
stepUser: string,
9+
userToBeCreated: string
10+
): Promise<void> {
11+
const admin = usersEnvironment.getUser({ key: stepUser })
12+
const user = usersEnvironment.getUser({ key: userToBeCreated })
13+
// do not try to create users when using predefined users
14+
if (!config.predefinedUsers) {
15+
await api.provision.createUser({ user, admin })
16+
}
17+
}
18+
19+
export async function userHasCreatedFolder(
20+
usersEnvironment: UsersEnvironment,
21+
stepUser: string,
22+
folderName: string
23+
): Promise<void> {
24+
const user = usersEnvironment.getUser({ key: stepUser })
25+
await api.dav.createFolderInsidePersonalSpace({ user, folder: folderName })
26+
}
27+
28+
export async function userHasSharedResource(
29+
usersEnvironment: UsersEnvironment,
30+
stepUser: string,
31+
resource: string,
32+
recipient: string,
33+
type: string,
34+
role: string,
35+
resourceType: ResourceType
36+
): Promise<void> {
37+
const user = usersEnvironment.getUser({ key: stepUser })
38+
await api.share.createShare({
39+
user,
40+
path: resource,
41+
shareType: type,
42+
shareWith: recipient,
43+
role: role,
44+
resourceType: resourceType as ResourceType
45+
})
46+
}
47+
48+
export async function userHasCreatedPublicLinkOfResource(
49+
usersEnvironment: UsersEnvironment,
50+
stepUser: string,
51+
resource: string,
52+
role: string,
53+
name?: string,
54+
password?: undefined,
55+
space?: 'Personal'
56+
) {
57+
const user = usersEnvironment.getUser({ key: stepUser })
58+
59+
await api.share.createLinkShare({
60+
user,
61+
path: resource,
62+
password: password,
63+
name: name ? name : 'Unnamed link',
64+
role: role,
65+
spaceName: space
66+
})
67+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { objects } from '../../../e2e/support'
2+
import { ActorsEnvironment, LinksEnvironment } from '../../../e2e/support/environment'
3+
4+
export async function openPublicLink(
5+
actorsEnvironment: ActorsEnvironment,
6+
linksEnvironment: LinksEnvironment,
7+
stepUser: string,
8+
name: string
9+
): Promise<void> {
10+
const { page } = await actorsEnvironment.createActor({
11+
key: stepUser,
12+
namespace: actorsEnvironment.generateNamespace(stepUser, stepUser)
13+
})
14+
15+
const { url } = linksEnvironment.getLink({ name })
16+
const pageObject = new objects.applicationFiles.page.Public({ page })
17+
await pageObject.open({ url })
18+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { objects } from '../../../e2e/support'
2+
import { ActorsEnvironment, FilesEnvironment } from '../../../e2e/support/environment'
3+
4+
export async function uploadResource(
5+
actorsEnvironment: ActorsEnvironment,
6+
filesEnvironment: FilesEnvironment,
7+
stepUser: string,
8+
resource: string,
9+
to: string,
10+
type?: string,
11+
option?: string
12+
): Promise<void> {
13+
const { page } = actorsEnvironment.getActor({ key: stepUser })
14+
const resourceObject = new objects.applicationFiles.Resource({ page })
15+
await resourceObject.upload({
16+
to: to,
17+
resources: [filesEnvironment.getFile({ name: resource })],
18+
option: option,
19+
type: type
20+
})
21+
}
22+
23+
export async function isAbleToEditFileOrFolder(
24+
actorsEnvironment: ActorsEnvironment,
25+
stepUser: string,
26+
resource: string
27+
): Promise<boolean> {
28+
const { page } = actorsEnvironment.getActor({ key: stepUser })
29+
const resourceObject = new objects.applicationFiles.Resource({ page })
30+
const userCanEdit = await resourceObject.canManageResource({ resource })
31+
return userCanEdit
32+
}

0 commit comments

Comments
 (0)