Compare commits

..

No commits in common. "develop" and "5.2.0" have entirely different histories.

754 changed files with 19338 additions and 29404 deletions

View File

@ -59,7 +59,7 @@
"error",
[
"/*!",
" * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.",
" * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.",
" *",
" * Alfresco Example Content Application",
" *",
@ -361,13 +361,6 @@
"playwright/valid-expect-in-promise": "off",
"playwright/valid-title": "off"
}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"comma-dangle": ["error", "never"]
}
}
]
}

View File

@ -1,26 +0,0 @@
share:
enabled: false
postgresql-sync:
enabled: false
alfresco-sync-service:
enabled: false
alfresco-digital-workspace:
enabled: false
alfresco-control-center:
enabled: false
alfresco-ai-transformer:
enabled: false
elasticsearch-audit:
enabled: false
alfresco-audit-storage:
enabled: false
kibana-audit:
enabled: false
alfresco-repository:
image:
tag: latest
global:
imagePullSecrets:
- name: regcred
alfrescoRegistryPullSecrets: regcred
known_urls: http://localhost

View File

@ -4,7 +4,7 @@ description: "ADF linking"
runs:
using: "composite"
steps:
- uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@v8.19.1
- uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@v8.2.0
- name: clone and install
shell: bash
run: |

9
.github/actions/after-e2e/action.yml vendored Normal file
View File

@ -0,0 +1,9 @@
name: "After e2e"
description: "Runs cleanup tasks after e2e run"
runs:
using: "composite"
steps:
- name: Remove storage file
shell: bash
run: rm -f ./storage-state/AdminUserState.json

View File

@ -1,79 +0,0 @@
name: deploy-local-acs
description: Deploy local ACS for E2E testing
inputs:
docker_username:
description: 'Docker username'
required: true
docker_password:
description: 'Docker password'
required: true
quay_username:
description: 'Quay username'
required: true
quay_password:
description: 'Quay password'
required: true
runs:
using: "composite"
steps:
- uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112
with:
version: "3.14.3"
- name: Login to Docker Hub
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ inputs.docker_username }}
password: ${{ inputs.docker_password }}
- name: Login to Quay.io
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: quay.io
username: ${{ inputs.quay_username }}
password: ${{ inputs.quay_password }}
- name: Setup cluster
uses: Alfresco/alfresco-build-tools/.github/actions/setup-kind@v8.19.1
with:
ingress-nginx-ref: controller-v1.8.2
- name: Set nginx ingress config
shell: bash
run: >-
kubectl -n ingress-nginx patch cm ingress-nginx-controller
-p '{"data": {"allow-snippet-annotations":"true"}}'
- name: Create registries auth secret
shell: bash
run: >-
kubectl create secret generic regcred
--from-file=.dockerconfigjson=$HOME/.docker/config.json
--type=kubernetes.io/dockerconfigjson
- name: Add dependency chart repos
shell: bash
run: |
helm repo add self https://alfresco.github.io/alfresco-helm-charts/
helm repo add elastic https://helm.elastic.co/
- name: Checkout acs-deployment sources
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
repository: Alfresco/acs-deployment
ref: v9.0.0
path: acs-deployment
- name: Helm install
shell: bash
run: >-
helm dep build acs-deployment/helm/alfresco-content-services &&
helm install acs acs-deployment/helm/alfresco-content-services
--set global.search.sharedSecret="$(openssl rand -hex 24)"
--values acs-deployment/test/enterprise-integration-test-values.yaml
--values .github/acs-deployment-values-override.yaml
- name: Wait for pods to be ready
uses: Alfresco/alfresco-build-tools/.github/actions/kubectl-wait@v8.19.1

View File

@ -5,6 +5,7 @@ inputs:
branch_name:
description: 'Name of the branch the workflow runs on'
required: true
type: string
runs:
using: "composite"
@ -12,7 +13,7 @@ runs:
- name: Get docker image tag name
shell: bash
run: |
if [[ "${{ inputs.branch_name }}" == "master" ]] || [[ "${{ inputs.branch_name }}" == release/* ]]; then
if [[ "${{ inputs.branch_name }}" == "master" ]]; then
TAG_VERSION="$(jq -cr '.version' < package.json)"
else
TAG_VERSION="${{ inputs.branch_name }}-${{ github.run_id }}"

View File

@ -5,12 +5,15 @@ inputs:
github_token:
description: 'Github token'
required: true
type: string
branch_name:
description: 'Name of the branch the workflow runs on'
required: true
type: string
dry-run:
description: dry run flag
required: true
type: boolean
runs:
using: "composite"
@ -18,7 +21,7 @@ runs:
- name: publish tag
shell: bash
run: |
if [[ "${{ inputs.branch_name }}" == "master" ]] || [[ "${{ inputs.branch_name }}" == release/* ]]; then
if [[ "${{ inputs.branch_name }}" == "master" ]]; then
VERSION=$(jq -cr '.version' < package.json)
echo "git tag -a ${VERSION} -m ${VERSION}"

View File

@ -5,18 +5,23 @@ inputs:
branch_name:
description: 'Name of the branch the workflow runs on'
required: true
type: string
github_token:
description: 'Github token'
required: true
type: string
npm_registry_token:
description: 'NPM registry token'
required: true
type: string
npm_tag:
description: 'NPM tag'
required: true
type: string
dry-run:
description: dry run flag
required: true
type: boolean
runs:
using: "composite"

View File

@ -5,13 +5,16 @@ inputs:
options:
description: 'Options'
required: true
type: string
test-runner:
description: 'Test runner'
required: false
type: string
default: 'Playwright'
artifact-name:
description: Name of the artifact cache
required: true
type: string
runs:
using: "composite"
@ -22,12 +25,7 @@ runs:
run: |
npm start > /dev/null &\
printf "Waiting for the application to be ready..."
while ! curl -sf ${PLAYWRIGHT_E2E_HOST} > /dev/null; do
printf "."
sleep 1
done
printf "\nApplication is ready.\n"
echo "Running playwright tests with options ${{ inputs.options }}"
sleep 90
npx nx run ${{ inputs.options }}-e2e:e2e

View File

@ -1,12 +1,6 @@
name: "Variables setup"
description: "Variables setup"
inputs:
npm_tag:
description: 'NPM tag'
required: false
type: string
runs:
using: "composite"
steps:
@ -19,19 +13,16 @@ runs:
echo "GIT_HASH=$(git rev-parse HEAD)" >> $GITHUB_ENV
echo "HEAD_HASH=HEAD" >> $GITHUB_ENV
- uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@v8.19.1
- uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@v8.2.0
- name: set TAG_NPM
shell: bash
run: |
if [[ -n "${{ inputs.npm_tag }}" ]]; then
TAG_NPM=${{ inputs.npm_tag }}
else
TAG_NPM="alpha"
VERSION_IN_PACKAGE_JSON=$(jq -cr '.version' < package.json)
echo "version in package.json=${VERSION_IN_PACKAGE_JSON}"
if [[ $BRANCH_NAME =~ ^master(-patch.*)?$ ]] || [[ $BRANCH_NAME == release/* ]]; then
if [[ $BRANCH_NAME =~ ^master(-patch.*)?$ ]]; then
# Pre-release versions
if [[ $VERSION_IN_PACKAGE_JSON =~ ^[0-9]*\.[0-9]*\.[0-9]*-A\.[0-9]*$ ]];
then
@ -45,5 +36,4 @@ runs:
if [[ $BRANCH_NAME =~ ^develop(-patch.*)?$ ]]; then
TAG_NPM=alpha
fi
fi
echo "TAG_NPM=${TAG_NPM}" >> $GITHUB_ENV

View File

@ -5,9 +5,11 @@ inputs:
branch_name:
description: 'Name of the branch the workflow runs on'
required: true
type: string
dry-run:
description: dry run flag
required: true
type: boolean
runs:
using: "composite"

View File

@ -61,12 +61,3 @@ updates:
github-actions:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/.github/actions/deploy-local-acs"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"

View File

@ -1,23 +0,0 @@
name: Pull Translations from Crowdin
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
jobs:
pull-from-crowdin:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Pull translations from Crowdin
uses: crowdin/github-action@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
with:
upload_sources: false
download_translations: true
create_pull_request: true
localization_branch_name: automated-translations-update
pull_request_title: "GH Auto: Automated Update of Translations from Crowdin"
pull_request_base_branch_name: develop
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TRANSLATIONS_TOKEN }}

View File

@ -12,14 +12,14 @@ concurrency:
cancel-in-progress: true
env:
BASE_URL: http://localhost
ADMIN_EMAIL: admin
ADMIN_PASSWORD: admin
HR_USER: admin
HR_USER_PASSWORD: admin
BASE_URL: ${{ secrets.PIPELINE_ENV_URL }}
ADMIN_EMAIL: ${{ secrets.PIPELINE_ADMIN_USERNAME }}
ADMIN_PASSWORD: ${{ secrets.PIPELINE_ADMIN_PASSWORD }}
HR_USER: ${{ secrets.HR_USER }}
HR_USER_PASSWORD: ${{ secrets.HR_USER_PASSWORD }}
SCREENSHOT_USERNAME: ${{ secrets.SCREENSHOT_USERNAME }}
SCREENSHOT_PASSWORD: ${{ secrets.SCREENSHOT_PASSWORD}}
PLAYWRIGHT_E2E_HOST: http://localhost:4200
PLAYWRIGHT_E2E_HOST: ${{ secrets.PLAYWRIGHT_E2E_HOST }}
GH_BUILD_NUMBER: ${{ github.run_id }}
REPORT_PORTAL_URL: ${{ secrets.REPORT_PORTAL_URL }}
REPORT_PORTAL_TOKEN: ${{ secrets.REPORT_PORTAL_TOKEN }}
@ -105,9 +105,7 @@ jobs:
e2es-playwright:
needs: [lint, build, unit-tests]
name: 'E2E Playwright - ${{ matrix.e2e-suites.name }}'
runs-on: ubuntu-24.04
env:
NODE_OPTIONS: --dns-result-order=ipv4first
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
@ -146,10 +144,6 @@ jobs:
id: 16
- name: "edit-actions"
id: 17
- name: "smoke-test"
id: 18
- name: "folder-information-actions"
id: 19
steps:
- name: Checkout
uses: actions/checkout@v4
@ -171,31 +165,18 @@ jobs:
path: ./dist/content-ce
key: cache-dist-${{ github.run_id }}
- name: Deploy local ACS
uses: ./.github/actions/deploy-local-acs
with:
docker_username: ${{ secrets.DOCKER_USERNAME }}
docker_password: ${{ secrets.DOCKER_PASSWORD }}
quay_username: ${{ secrets.QUAY_USERNAME }}
quay_password: ${{ secrets.QUAY_PASSWORD }}
- name: Before e2e
uses: ./.github/actions/before-e2e
- name: Before playwright
- name: before playwright
shell: bash
run: npx playwright install chromium
- uses: ./.github/actions/run-e2e-playwright
with:
options: "${{ matrix.e2e-suites.name }}"
artifact-name: ${{ matrix.e2e-suites.name }}
test-runner: playwright
- name: Debug Ingress Controller Logs
if: always()
run: |
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=-1
- uses: ./.github/actions/after-e2e
finalize:
if: ${{ always() }}
@ -217,7 +198,7 @@ jobs:
fetch-depth: 2
- name: Extract commit message
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@v8.19.1
uses: Alfresco/alfresco-build-tools/.github/actions/get-commit-message@v8.2.0
- name: Check ADF link
shell: bash

87
.github/workflows/release-branch.yml vendored Normal file
View File

@ -0,0 +1,87 @@
name: Release ACA libs from branch
run-name: Release ACA libs from branch ${{ github.ref_name }}
on:
workflow_dispatch:
inputs:
dry-run-flag:
description: 'enable dry-run'
required: false
type: boolean
default: true
env:
BASE_URL: ${{ secrets.PIPELINE_ENV_URL }}
jobs:
lint:
name: 'lint'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- run: npm run affected:lint -- --base=origin/develop
- run: npm run stylelint
unit-tests:
needs: [lint]
name: "Unit tests: ${{ matrix.unit-tests.name }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
unit-tests:
- name: "aca-content"
- name: "aca-shared"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: ./.github/actions/before-install
- run: npm ci
- run: npm run affected:test -- --browsers=ChromeHeadless --watch=false $TEST_OPTS --base=origin/develop
publish-libs:
needs: [lint, unit-tests]
name: "Publish libs to NPM and GitHub registry"
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: Alfresco/alfresco-build-tools/.github/actions/get-branch-name@v8.2.0
- name: publish
uses: ./.github/actions/publish-libs
with:
branch_name: ${{ env.BRANCH_NAME }}
github_token: ${{ secrets.BOT_GITHUB_TOKEN }}
npm_registry_token: ${{ secrets.NPM_REGISTRY_TOKEN }}
npm_tag: 'branch'
dry-run: ${{ inputs.dry-run-flag }}

View File

@ -1,36 +1,10 @@
name: Release workflow
run-name: Release workflow triggered from ${{ github.ref_name }} branch
name: "Release"
on:
workflow_dispatch:
inputs:
publish-to-docker:
description: 'Publish to Docker'
required: false
type: boolean
default: true
publish-to-quay:
description: 'Publish to Quay'
required: false
type: boolean
default: true
publish-to-npm:
description: 'Publish NPM libraries'
required: false
type: boolean
default: true
publish-git-tag:
description: 'Publish Git Tag'
required: false
type: boolean
default: true
npm-tag:
description: 'NPM tag that libraries will be published with'
required: false
type: string
default: ''
dry-run-release:
description: 'Enable dry-run'
description: 'enable dry-run'
required: false
type: boolean
default: true
@ -38,7 +12,6 @@ on:
branches:
- master
- develop
- release/**
env:
BASE_URL: ${{ secrets.PIPELINE_ENV_URL }}
@ -47,61 +20,10 @@ env:
PLAYWRIGHT_E2E_HOST: ${{ secrets.PLAYWRIGHT_E2E_HOST }}
jobs:
lint:
if: github.event_name == 'workflow_dispatch'
name: 'lint'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- run: npm ci
- run: npm run affected:lint -- --base=origin/develop
- run: npm run stylelint
unit-tests:
if: github.event_name == 'workflow_dispatch'
needs: [lint]
name: "Unit tests: ${{ matrix.unit-tests.name }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
unit-tests:
- name: "aca-content"
- name: "aca-shared"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: node
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: ./.github/actions/before-install
- run: npm ci
- run: npm run affected:test -- --browsers=ChromeHeadless --watch=false $TEST_OPTS --base=origin/develop
publish-docker-registry:
if: ${{ always() }}
needs: [lint, unit-tests]
name: "Publish to Quay"
runs-on: ubuntu-latest
steps:
- name: Check previous jobs status
if: ${{ inputs.publish-to-quay == 'false' || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: Checkout
uses: actions/checkout@v4
with:
@ -112,8 +34,6 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: ./.github/actions/setup
with:
npm_tag: ${{ inputs.npm-tag }}
- name: Get Tag
uses: ./.github/actions/get-image-tag
@ -130,15 +50,9 @@ jobs:
dry-run: ${{ inputs.dry-run-release }}
publish-to-dockerhub:
if: ${{ always() }}
needs: [lint, unit-tests]
name: "Publish to Dockerhub"
runs-on: ubuntu-latest
steps:
- name: Check previous jobs status
if: ${{ inputs.publish-to-docker == 'false' || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: Checkout
uses: actions/checkout@v4
with:
@ -149,8 +63,6 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: ./.github/actions/setup
with:
npm_tag: ${{ inputs.npm-tag }}
- name: Get Tag
uses: ./.github/actions/get-image-tag
@ -167,15 +79,9 @@ jobs:
dry-run: ${{ inputs.dry-run-release }}
publish-git-tag:
if: ${{ always() }}
needs: [lint, unit-tests]
name: "Publish Git Tag"
runs-on: ubuntu-latest
steps:
- name: Check previous jobs status
if: ${{ inputs.publish-git-tag == 'false' || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: Checkout
uses: actions/checkout@v4
with:
@ -186,9 +92,7 @@ jobs:
node-version-file: '.nvmrc'
cache: 'npm'
- uses: ./.github/actions/setup
with:
npm_tag: ${{ inputs.npm-tag }}
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.19.1
- uses: Alfresco/alfresco-build-tools/.github/actions/configure-git-author@v8.2.0
with:
username: ${{ vars.BOT_GITHUB_USERNAME }}
email: ${{ vars.BOT_GITHUB_EMAIL }}
@ -201,17 +105,11 @@ jobs:
dry-run: ${{ inputs.dry-run-release }}
publish-libs:
if: ${{ always() }}
needs: [lint, unit-tests]
name: "Publish libs to NPM and GitHub registry"
runs-on: ubuntu-latest
permissions:
packages: write
steps:
- name: Check previous jobs status
if: ${{ inputs.publish-to-npm == 'false' || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
run: exit 1
- name: Checkout
uses: actions/checkout@v4
with:
@ -224,8 +122,6 @@ jobs:
cache: 'npm'
- uses: ./.github/actions/setup
with:
npm_tag: ${{ inputs.npm-tag }}
- name: publish
uses: ./.github/actions/publish-libs
@ -235,23 +131,3 @@ jobs:
npm_registry_token: ${{ secrets.NPM_REGISTRY_TOKEN }}
npm_tag: ${{ env.TAG_NPM }}
dry-run: ${{ inputs.dry-run-release }}
push-translation-keys-to-crowdin:
name: Push translations keys to Crowdin
if: ${{ github.ref == 'refs/heads/develop' }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
actions: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Push Source Files to Crowdin
uses: crowdin/github-action@b8012bd5491b8aa8578b73ab5b5f5e7c94aaa6e2 # v2.7.0
with:
upload_sources: true
upload_sources_args: --delete-obsolete
env:
CROWDIN_TOKEN: ${{ secrets.CROWDIN_TRANSLATIONS_TOKEN }}

2
.nvmrc
View File

@ -1 +1 @@
20.18.1
18

View File

@ -1,6 +1,6 @@
# 1. Generate licenses
FROM node:20.18-alpine3.21 AS builder
FROM node:18.16-alpine3.17 AS builder
WORKDIR /usr/src/alfresco
COPY package.json package.json

View File

@ -12,9 +12,7 @@ Please refer to the public [documentation](https://alfresco-content-app.netlify.
## Compatibility
| ACA | ADF | ACS | Node | Angular |
|-------|---------------|-----------|------|---------|
| 6.0.x | 7.0.0 | 25.1 | 20.x | 17.x |
| 5.3.x | 7.0.0-alpha.7 | 23.4 | 18.x | 16.x |
|-------|---------------|-----------|------|--------|
| 5.2.x | 7.0.0-alpha.6 | 23.4 | 18.x | 16.x |
| 5.1.x | 7.0.0-alpha.3 | 23.3 | 18.x | 15.x |
| 5.0.x | 7.0.0-alpha.2 | 23.3 | 18.x | 15.x |

View File

@ -41,7 +41,7 @@
"output": "/assets"
},
{
"glob": "pdf.worker.min.mjs",
"glob": "pdf.worker.min.js",
"input": "node_modules/pdfjs-dist/build",
"output": "/"
},
@ -89,19 +89,10 @@
"styles": [
"node_modules/cropperjs/dist/cropper.min.css",
"node_modules/pdfjs-dist/web/pdf_viewer.css",
"node_modules/katex/dist/katex.min.css",
"node_modules/prismjs/themes/prism-okaidia.css",
"projects/aca-content/src/lib/ui/application.scss",
"app/src/styles.scss"
],
"scripts": [
"node_modules/mermaid/dist/mermaid.min.js",
"node_modules/katex/dist/katex.min.js",
"node_modules/katex/dist/contrib/auto-render.min.js",
"node_modules/prismjs/prism.js",
"node_modules/prismjs/components/prism-csharp.min.js",
"node_modules/prismjs/components/prism-css.min.js"
],
"scripts": ["node_modules/pdfjs-dist/build/pdf.js", "node_modules/pdfjs-dist/web/pdf_viewer.js"],
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,

View File

@ -35,7 +35,7 @@
"locale": "en",
"application": {
"name": "Workspace",
"version": "5.3.0",
"version": "5.2.0",
"logo": "assets/images/app-logo.svg",
"copyright": "APP.COPYRIGHT"
},
@ -126,7 +126,6 @@
},
"search-headers": {
"filterWithContains": true,
"include": ["path", "allowableOperations", "properties"],
"app:fields": [
"cm:name",
"cm:title",

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -23,6 +23,7 @@
*/
import { Component, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { AppService } from '@alfresco/aca-shared';
@Component({
@ -32,6 +33,8 @@ import { AppService } from '@alfresco/aca-shared';
encapsulation: ViewEncapsulation.None
})
export class AppComponent {
onDestroy$: Subject<boolean> = new Subject<boolean>();
constructor(private appService: AppService) {
this.appService.init();
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,13 +0,0 @@
"project_id": "13"
"api_token_env": "CROWDIN_TOKEN"
"base_path": "."
"base_url": "https://hyland.api.crowdin.com"
"preserve_hierarchy": true
"files": [
{
"source": "/**/**/i18n/en.json",
"translation": "/%original_path%/%two_letters_code%.%file_extension%",
"export_only_approved": "true",
"update_option": "update_as_unapproved"
}
]

View File

@ -40,8 +40,6 @@ The documentation is divided into the following sections:
| ACA | ADF | ACS | Node | Angular |
|-------|---------------|-----------|------|---------|
| 6.0.x | 7.0.0 | 25.1 | 20.x | 17.x |
| 5.3.x | 7.0.0-alpha.7 | 23.4 | 18.x | 16.x |
| 5.2.x | 7.0.0-alpha.6 | 23.4 | 18.x | 16.x |
| 5.1.x | 7.0.0-alpha.3 | 23.3 | 18.x | 15.x |
| 5.0.x | 7.0.0-alpha.2 | 23.3 | 18.x | 15.x |

View File

@ -1,25 +0,0 @@
---
Title: Audit info, alfresco-content-app 5.3.0
---
# Audit information for alfresco-content-app 5.3.0
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 2
- Moderate risk: 0
- Low risk: 0
Dependencies analyzed:
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
|high | @alfresco/adf-core | &#34;&lt;=2.7.0-fee35c98df520c917e22b6bb19cba1d697365d75 || &gt;=6.10.0-9127362140&#34; |
|high | pdfjs-dist | &#34;&lt;=4.1.392&#34; |

View File

@ -1,25 +0,0 @@
---
Title: Audit info, alfresco-content-app 6.0.0
---
# Audit information for alfresco-content-app 6.0.0
This page lists the security audit of the dependencies this project depends on.
## Risks
- Critical risk: 0
- High risk: 1
- Moderate risk: 1
- Low risk: 0
Dependencies analyzed:
## Libraries
| Severity | Module | Vulnerable versions |
| --- | --- | --- |
|moderate | @babel/runtime | &#34;&lt;7.26.10&#34; |
|high | pdfjs-dist | &#34;&lt;=4.1.392&#34; |

View File

@ -1,32 +0,0 @@
---
Title: Changelog for alfresco-content-app v5.3.0
---
# Changelog
- [1b170f69e](https://github.com/Alfresco/alfresco-content-app.git//commit/1b170f69e) Revert &#34;[ACS-9166] Migrate Saved Searches to preferences API from config file…&#34; (#4347)
- [0dfd2c17a](https://github.com/Alfresco/alfresco-content-app.git//commit/0dfd2c17a) [ACS-9166] Migrate Saved Searches to preferences API from config file (#4340)
- [52b4060e7](https://github.com/Alfresco/alfresco-content-app.git//commit/52b4060e7) [ACS-8960] Review and apply required inputs where possible (#4339)
- [d30c93325](https://github.com/Alfresco/alfresco-content-app.git//commit/d30c93325) [MNT-24575] Added dialog to display folder information (#4282)
- [72e740502](https://github.com/Alfresco/alfresco-content-app.git//commit/72e740502) [ACS-6486] in breadcrumb the file title is not updating after editing (#4337)
- [8931a295c](https://github.com/Alfresco/alfresco-content-app.git//commit/8931a295c) [ACS-9102] Local ACS deployment for E2Es (#4324)
- [3f6d08247](https://github.com/Alfresco/alfresco-content-app.git//commit/3f6d08247) ACA-playwright-package-version-fix (#4323)
- [539408862](https://github.com/Alfresco/alfresco-content-app.git//commit/539408862) ACS-9039 fix for export aca-playwright-shared lib (#4317)
- [a6057763c](https://github.com/Alfresco/alfresco-content-app.git//commit/a6057763c) [ACS-9088] Review and update docs on extension creation (#4312)
- [03e505a89](https://github.com/Alfresco/alfresco-content-app.git//commit/03e505a89) [ACS-8902] Fixed incorrect icon for join library option (#4310)
- [d6f859dd7](https://github.com/Alfresco/alfresco-content-app.git//commit/d6f859dd7) [ACS-8961] Remove expandedSidenav from local storage upon logout (#4242)
- [65763df7e](https://github.com/Alfresco/alfresco-content-app.git//commit/65763df7e) [ACS-8604] Add new param to control undo for deleting nodes (#4308)
- [111f3f99e](https://github.com/Alfresco/alfresco-content-app.git//commit/111f3f99e) [ACS-8998] Added validation to search input to disallow certain special characters (#4253)
- [af6deb438](https://github.com/Alfresco/alfresco-content-app.git//commit/af6deb438) [ACS-8160] apply styles for tags in info drawer (#4126)
- [7fcc0af5b](https://github.com/Alfresco/alfresco-content-app.git//commit/7fcc0af5b) Manual dependencies update (#4298)
- [93157d2e6](https://github.com/Alfresco/alfresco-content-app.git//commit/93157d2e6) [ACS-9012] Truncate text in saved searches description (#4265)
- [85b4455b0](https://github.com/Alfresco/alfresco-content-app.git//commit/85b4455b0) Test translation cleanup (#4285)
- [58e21189f](https://github.com/Alfresco/alfresco-content-app.git//commit/58e21189f) Test translation added (#4283)
- [f5ca67cc2](https://github.com/Alfresco/alfresco-content-app.git//commit/f5ca67cc2) [ACS-9042] Introduce Crowdin related workflows and Crowdin config (#4281)
- [6734da982](https://github.com/Alfresco/alfresco-content-app.git//commit/6734da982) [ACS-8999] rename confirmation button label for closing conversation dialog (#4261)
- [a37fec5a7](https://github.com/Alfresco/alfresco-content-app.git//commit/a37fec5a7) [ACS-9010] Loading spinner is not shown on search results page when filtering for files or folders (#4263)
- [4cb6e5691](https://github.com/Alfresco/alfresco-content-app.git//commit/4cb6e5691) [ACS-8993] [E2E] fixed expect in sorting order for C261147 (#4262)
- [f8c6b6bbd](https://github.com/Alfresco/alfresco-content-app.git//commit/f8c6b6bbd) [ACS-8898] Empty context menu on multi-selected libraries (#4260)
- [7985f76b5](https://github.com/Alfresco/alfresco-content-app.git//commit/7985f76b5) Post release version bump (#4250)
- [adda597f1](https://github.com/Alfresco/alfresco-content-app.git//commit/adda597f1) [ACS-8959] Introduce new `takeUntilDestroyed` operator (#4237)

View File

@ -1,40 +0,0 @@
---
Title: Changelog for alfresco-content-app v6.0.0
---
# Changelog
- [0e7610919](git@github.com:Alfresco/alfresco-content-app/commit/0e7610919) [ACS-9371] Migrate docs from docs.alfresco to support.hyland (#4446)
- [2a509abeb](git@github.com:Alfresco/alfresco-content-app/commit/2a509abeb) [ACS-9364] Update upload.e2e.ts tests to have proper expects (#4427)
- [5bc0214e0](git@github.com:Alfresco/alfresco-content-app/commit/5bc0214e0) Bump tests environment to latest chart/tag (#4440)
- [651212da6](git@github.com:Alfresco/alfresco-content-app/commit/651212da6) Use kubectl-wait action (#4437)
- [c8850bcd1](git@github.com:Alfresco/alfresco-content-app/commit/c8850bcd1) Update angular/cli (#4433)
- [2e6229b77](git@github.com:Alfresco/alfresco-content-app/commit/2e6229b77) [ACS-9346] Use visibility rules as array (#4430)
- [2efea8c6d](git@github.com:Alfresco/alfresco-content-app/commit/2efea8c6d) Rollback visibility rules cleanup (#4426)
- [4e37f194a](git@github.com:Alfresco/alfresco-content-app/commit/4e37f194a) [ACS-9225] serious a11y testing side bar elements must meet minimum color contrast ratio thresholds (#4425)
- [9724f4625](git@github.com:Alfresco/alfresco-content-app/commit/9724f4625) [ACA-4735] Fix search input focus styles (#4418)
- [03b5ac83c](git@github.com:Alfresco/alfresco-content-app/commit/03b5ac83c) [ACS-9291] [ACA] [E2E] Automate XAT-5488, XAT-5490 (#4405)
- [b3e2af7f0](git@github.com:Alfresco/alfresco-content-app/commit/b3e2af7f0) [ACS-9369] Updated rule-migration-guide.md to include missed rule (#4420)
- [4e33f1126](git@github.com:Alfresco/alfresco-content-app/commit/4e33f1126) [ACS-9369] Resolved issues where visibility rules with a single element array would log errors (#4416)
- [34c52ac42](git@github.com:Alfresco/alfresco-content-app/commit/34c52ac42) [MNT-24892] Upgrade Node to 20 (#4415)
- [0696ce82b](git@github.com:Alfresco/alfresco-content-app/commit/0696ce82b) [ACS-9344] change permissions error message for opening records management library (#4414)
- [f1c4dcf45](git@github.com:Alfresco/alfresco-content-app/commit/f1c4dcf45) [ACS-8694] Cleanup of visibility rules for extensions in ACA (#4140)
- [4751dcd12](git@github.com:Alfresco/alfresco-content-app/commit/4751dcd12) [ACS-9158] Remove &#39;View Details&#39; button from node Details page (#4351)
- [c79904979](git@github.com:Alfresco/alfresco-content-app/commit/c79904979) [ACS-8782] list of frozen files under a hold (#4406)
- [a99ca755e](git@github.com:Alfresco/alfresco-content-app/commit/a99ca755e) ACS-9201 create smoke test suite (#4361)
- [261cdaebe](git@github.com:Alfresco/alfresco-content-app/commit/261cdaebe) [ACS-9266] Make notification and user menu accessible with keyboard (#4394)
- [a70378bff](git@github.com:Alfresco/alfresco-content-app/commit/a70378bff) [ACS-6849][ACA] Upgrade to Angular 17 (#4275)
- [b01381864](git@github.com:Alfresco/alfresco-content-app/commit/b01381864) [ACS-9187] [E2E] Fix XAT-5304 - file downloading is flaky (#4375)
- [2093a7acc](git@github.com:Alfresco/alfresco-content-app/commit/2093a7acc) [ACS-9229] a11y testing: Search Page / Elements must only use supported ARIA attributes (#4383)
- [5bd835716](git@github.com:Alfresco/alfresco-content-app/commit/5bd835716) AAE-30880 Remove usage of commonjs buffer package (#4379)
- [6a5e89499](git@github.com:Alfresco/alfresco-content-app/commit/6a5e89499) [ACS-9235] a11y testing: Breadcrumbs / Back Arrow / Buttons must have discernible text (#4384)
- [0446ef609](git@github.com:Alfresco/alfresco-content-app/commit/0446ef609) [ACS-9236] a11y testing: Create Rule - Buttons must have discernible text (#4381)
- [85e0b4335](git@github.com:Alfresco/alfresco-content-app/commit/85e0b4335) [ACS-9228] a11y testing: Search Page / Buttons must have discernible text (#4376)
- [e0fa9d6d5](git@github.com:Alfresco/alfresco-content-app/commit/e0fa9d6d5) [ACS-9213] Update license visible on login page from SSO (#4373)
- [09636b377](git@github.com:Alfresco/alfresco-content-app/commit/09636b377) [ACS-9211] Update license headers (#4372)
- [f01d6e161](git@github.com:Alfresco/alfresco-content-app/commit/f01d6e161) [ACS-9154] Fix unstable tests in ACA after migration to local ACS (#4341)
- [75f25e974](git@github.com:Alfresco/alfresco-content-app/commit/75f25e974) [ACS-9083][ADW] Comment creation is available after document is retained (declared as record) (#4359)
- [02caa7acb](git@github.com:Alfresco/alfresco-content-app/commit/02caa7acb) [ACS-9119] Saved Search navbar title now gets translated (#4356)
- [3bfeca3b8](git@github.com:Alfresco/alfresco-content-app/commit/3bfeca3b8) [ACS-9166] Migrate Saved Searches to preferences API from config file (#4358)
- [0286d08b6](git@github.com:Alfresco/alfresco-content-app/commit/0286d08b6) Post release version bump (#4357)

View File

@ -198,7 +198,7 @@ The button will be visible only when the linked rule evaluates to `true`.
## Application Evaluators
| Ver. | Key | Description |
|--------|-------------------------------------|---------------------------------------------------------------------------------------------------|
| ----- | ----------------------------------- | ------------------------------------------------------------------------ |
| 1.7.0 | app.selection.canDelete | User has permission to delete selected node(s). |
| 1.7.0 | app.selection.canDownload | User can download selected node(s). |
| 1.7.0 | app.selection.notEmpty | At least one node is selected. |
@ -236,7 +236,6 @@ The button will be visible only when the linked rule evaluates to `true`.
| 1.8.0 | user.isAdmin | Checks if user is admin. |
| 1.9.0 | app.canShowLogout | Whether logout action should be present or not. |
| 1.12.0 | app.isLibraryManager | Checks if user is library manager. |
| 6.1.0 | canPrintFile | Checks if current file can be printed or not (media files such as audio/video cannot be printed). |
## Navigation Evaluators
@ -249,7 +248,7 @@ for example mixing `core.every` and `core.not`.
`!app.navigation.isTrashcan` is the opposite of the `app.navigation.isTrashcan`.
| Version | Key | Description |
|---------|-----------------------------------|------------------------------------------------------------------|
| ------- | --------------------------------- | ---------------------------------------------------------------- |
| 1.7.0 | app.navigation.folder.canCreate | User can create content in the currently opened folder. |
| 1.7.0 | app.navigation.folder.canUpload | User can upload content to the currently opened folder. |
| 1.7.0 | app.navigation.isTrashcan | User is using the **Trashcan** page. |
@ -270,7 +269,6 @@ for example mixing `core.every` and `core.not`.
| 1.7.0 | app.navigation.isPreview | Current page is **Preview**. |
| 1.7.0 | app.navigation.isPersonalFiles | Current page is **Personal Files**. |
| 1.7.0 | app.navigation.isLibraryFiles | Current page is **Library Files**. |
| 5.3.0 | app.navigation.isNotDetails | Current page is not **Details**. |
**Tip:** See the [Registration](./registration) section for more details
on how to register your own entries to be re-used at runtime.

View File

@ -26,6 +26,6 @@ In order to configure multiple search form you have to add your search configura
In order to learn more about :
-The search UI configuration possibilities refer to the [ADF Search configuration documentation](https://github.com/Alfresco/alfresco-ng2-components/blob/develop/docs/user-guide/search-configuration-guide.md)
-The search Query configuration possibilities refer to the [Full text search reference documentation](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference)
-The search Query configuration possibilities refer to the [Full text search reference documentation](https://docs.alfresco.com/search-services/latest/using/)

View File

@ -22,33 +22,33 @@ And also the Info Drawer, Toolbar and Node Selector dialogs for copy and move op
## Alfresco Full Text Search
The following table describes current support of the
[Alfresco Full Text Search](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference) (FTS) syntax
[Alfresco Full Text Search](http://docs.alfresco.com/6.1/concepts/rm-searchsyntax-intro.html) (FTS) syntax
in the Content Application when using **Search Input** component.
| Feature | Full | Partial | N/A | Details |
| ---------------------------------------------------------------- | ---- | ------- | --- | ---------------------------------------------------------------------------------- |
| Search for a single term | 1.6 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-a-single-term) |
| Search for a phrase | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-a-phrase) |
| Search for an exact term | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-an-exact-term) |
| Search for term expansion | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-term-expansion) |
| Search for conjunctions | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Enterprise/4.1/Alfresco-Search-Enterprise/Using/Search-query-syntax/Search-for-conjunctions) |
| Search for disjunctions | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-disjunctions) |
| Search for negation | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-negation) |
| Search for optional, mandatory, and excluded elements of a query | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-optional-mandatory-and-excluded-elements-of-a-query) |
| Search in fields | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-in-fields) |
| Search for wildcards | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-wildcards) |
| Search for ranges | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-ranges) |
| Search for fuzzy matching | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-fuzzy-matching) |
| Search for proximity | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-proximity) |
| Search for boosts | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Query-time-boosts) |
| Search for grouping | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-grouping) |
| Search for spans and positions | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-spans-and-positions) |
| Escaping characters | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Escaping-characters) |
| Mixed FTS ID behavior | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Mixed-FTS-ID-behavior) |
| Search for operator precedence | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-operator-precedence) |
| Search query templates | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-query-templates) |
| Search query literals | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-query-literals) |
| Search using date math | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-using-date-math) |
| Search for a single term | 1.6 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-single.html) |
| Search for a phrase | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-phrase.html) |
| Search for an exact term | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-exact.html) |
| Search for term expansion | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-term.html) |
| Search for conjunctions | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-conjunct.html) |
| Search for disjunctions | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-disjunct.html) |
| Search for negation | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-negate.html) |
| Search for optional, mandatory, and excluded elements of a query | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-optional.html) |
| Search in fields | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fields.html) |
| Search for wildcards | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-wildcards.html) |
| Search for ranges | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ranges.html) |
| Search for fuzzy matching | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fuzzy.html) |
| Search for proximity | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-proximity.html) |
| Search for boosts | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-boosts.html) |
| Search for grouping | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-grouping.html) |
| Search for spans and positions | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-spans.html) |
| Escaping characters | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-escaping.html) |
| Mixed FTS ID behavior | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ftsid.html) |
| Search for operator precedence | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-precedence.html) |
| Search query templates | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-querytemplates.html) |
| Search query literals | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-literals.html) |
| Search using date math | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-datemaths.html) |
> **Partial** support means the feature supports basic scenarios
> and there are edge cases that are not yet fully tested and might not work.

View File

@ -7,7 +7,7 @@ Title: Single Sign-On
Besides Basic Authentication, you can use Content Application with:
- [Keycloak](https://www.keycloak.org/)
- [Identity Service](https://support.hyland.com/r/Alfresco/Alfresco-Process-Services/24.3/Alfresco-Process-Services/Configure/Authentication/Identity-Service)
- [Identity Service](https://docs.alfresco.com/identity1.0/concepts/identity-overview.html)
- Kerberos
The application contains reasonable defaults for Single Sign-On (aka SSO) setup.

View File

@ -23,33 +23,33 @@ nav: ja
## Alfresco 全文検索
次の表は、**検索入力**コンポーネントを使用する場合のコンテンツアプリケーションでの
[Alfresco 全文検索](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference) (FTS) 構文の
[Alfresco 全文検索](http://docs.alfresco.com/6.1/concepts/rm-searchsyntax-intro.html) (FTS) 構文の
現在のサポートについて説明しています。
| 機能 | フル | 部分的 | N/A | 詳細 |
| ---------------------------------------------------------------- | ---- | ------- | --- | ---------------------------------------------------------------------------------- |
| Search for a single term | 1.6 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-a-single-term) |
| Search for a phrase | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-a-phrase) |
| Search for an exact term | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-an-exact-term) |
| Search for term expansion | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-term-expansion) |
| Search for conjunctions | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Enterprise/4.1/Alfresco-Search-Enterprise/Using/Search-query-syntax/Search-for-conjunctions) |
| Search for disjunctions | 1.7 | | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-disjunctions) |
| Search for negation | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-negation) |
| Search for optional, mandatory, and excluded elements of a query | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-optional-mandatory-and-excluded-elements-of-a-query) |
| Search in fields | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-in-fields) |
| Search for wildcards | | 1.7 | | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-wildcards) |
| Search for ranges | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-ranges) |
| Search for fuzzy matching | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-fuzzy-matching) |
| Search for proximity | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-proximity) |
| Search for boosts | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Query-time-boosts) |
| Search for grouping | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-grouping) |
| Search for spans and positions | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-spans-and-positions) |
| Escaping characters | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Escaping-characters) |
| Mixed FTS ID behavior | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Mixed-FTS-ID-behavior) |
| Search for operator precedence | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-for-operator-precedence) |
| Search query templates | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-query-templates) |
| Search query literals | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-query-literals) |
| Search using date math | | | X | [Docs](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference/Search-using-date-math) |
| Search for a single term | 1.6 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-single.html) |
| Search for a phrase | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-phrase.html) |
| Search for an exact term | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-exact.html) |
| Search for term expansion | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-term.html) |
| Search for conjunctions | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-conjunct.html) |
| Search for disjunctions | 1.7 | | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-disjunct.html) |
| Search for negation | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-negate.html) |
| Search for optional, mandatory, and excluded elements of a query | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-optional.html) |
| Search in fields | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fields.html) |
| Search for wildcards | | 1.7 | | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-wildcards.html) |
| Search for ranges | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ranges.html) |
| Search for fuzzy matching | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-fuzzy.html) |
| Search for proximity | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-proximity.html) |
| Search for boosts | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-boosts.html) |
| Search for grouping | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-grouping.html) |
| Search for spans and positions | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-spans.html) |
| Escaping characters | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-escaping.html) |
| Mixed FTS ID behavior | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-ftsid.html) |
| Search for operator precedence | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-precedence.html) |
| Search query templates | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-querytemplates.html) |
| Search query literals | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-literals.html) |
| Search using date math | | | X | [Docs](https://docs.alfresco.com/6.0/concepts/rm-searchsyntax-datemaths.html) |
> **部分的**なサポートとは、この機能が基本的なシナリオをサポートすることを意味し、
> まだ完全にはテストされておらず動作しない可能性があるエッジケースがあります。

View File

@ -13,5 +13,5 @@ nav: ja
**注:** ソースコードからローカルにビルドするには、[Node.js](https://nodejs.org/ja/) (LTS) もインストールする必要があります。
アプリケーションは最新の [REST API](https://api-explorer.alfresco.com/api-explorer/) を使用して開発されているため、
アプリケーションは最新の [REST API](https://docs.alfresco.com/5.2/pra/1/topics/pra-welcome.html) を使用して開発されているため、
Alfresco Content プラットフォームの最新バージョンが必要です。

View File

@ -8,7 +8,7 @@ nav: ja
Basic 認証に加えて、Content Application を以下で使用できます:
- [Keycloak](https://www.keycloak.org/)
- [Identity Service](https://support.hyland.com/r/Alfresco/Alfresco-Process-Services/24.3/Alfresco-Process-Services/Configure/Authentication/Identity-Service)
- [Identity Service](https://docs.alfresco.com/identity1.0/concepts/identity-overview.html)
- Kerberos
アプリケーションには、シングルサインオン (別名 SSO) セットアップの適切なデフォルトの設定が含まれています。

View File

@ -1,44 +0,0 @@
---
Title: License info, alfresco-content-app 5.3.0
---
# License information for alfresco-content-app 5.3.0
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@alfresco/adf-content-services](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0-alpha.7 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/adf-core](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0-alpha.7 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/adf-extensions](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0-alpha.7 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/eslint-plugin-eslint-angular](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0-alpha.7 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/js-api](https://github.com/Alfresco/alfresco-ng2-components) | 8.0.0-alpha.7 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@angular/animations](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/cdk](https://github.com/angular/components) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/common](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/compiler](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/core](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/forms](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material](https://github.com/angular/components) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/router](https://github.com/angular/angular) | 16.2.9 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@fontsource/open-sans](https://github.com/fontsource/font-files) | 5.1.0 | [OFL-1.1](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker) | 12.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/effects](https://github.com/ngrx/platform) | 16.3.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/router-store](https://github.com/ngrx/platform) | 16.3.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/store-devtools](https://github.com/ngrx/platform) | 16.3.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/store](https://github.com/ngrx/platform) | 16.3.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 14.0.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [material-icons](https://github.com/marella/material-icons) | 1.13.12 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch-browser](https://github.com/isaacs/minimatch) | 1.0.0 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [pdfjs-dist](https://github.com/mozilla/pdfjs-dist) | 3.3.122 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [rxjs](https://github.com/reactivex/rxjs) | 7.8.1 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [tslib](https://github.com/Microsoft/tslib) | 1.14.1 | [0BSD](http://landley.net/toybox/license.html) |
| [tslib](https://github.com/Microsoft/tslib) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [zone.js](https://github.com/angular/angular) | 0.13.3 | [MIT](http://www.opensource.org/licenses/MIT) |

View File

@ -1,43 +0,0 @@
---
Title: License info, alfresco-content-app 6.0.0
---
# License information for alfresco-content-app 6.0.0
This page lists all third party libraries the project depends on.
## Libraries
| Name | Version | License |
| --- | --- | --- |
| [@alfresco/adf-content-services](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/adf-core](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/adf-extensions](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/eslint-plugin-eslint-angular](https://github.com/Alfresco/alfresco-ng2-components) | 7.0.0 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@alfresco/js-api](https://github.com/Alfresco/alfresco-ng2-components) | 8.0.0 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [@angular/animations](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/cdk](https://github.com/angular/components) | 17.1.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/common](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/compiler](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/core](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/forms](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material-date-fns-adapter](https://github.com/angular/components) | 17.1.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/material](https://github.com/angular/components) | 17.1.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/platform-browser](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@angular/router](https://github.com/angular/angular) | 17.1.3 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@fontsource/open-sans](https://github.com/fontsource/font-files) | 5.2.5 | [OFL-1.1](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web) |
| [@mat-datetimepicker/core](https://github.com/kuhnroyal/mat-datetimepicker) | 13.0.2 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/effects](https://github.com/ngrx/platform) | 17.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/router-store](https://github.com/ngrx/platform) | 17.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/store-devtools](https://github.com/ngrx/platform) | 17.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngrx/store](https://github.com/ngrx/platform) | 17.0.1 | [MIT](http://www.opensource.org/licenses/MIT) |
| [@ngx-translate/core](https://github.com/ngx-translate/core) | 14.0.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [date-fns](https://github.com/date-fns/date-fns) | 2.30.0 | [MIT](http://www.opensource.org/licenses/MIT) |
| [material-icons](https://github.com/marella/material-icons) | 1.13.14 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [minimatch-browser](https://github.com/isaacs/minimatch) | 1.0.0 | [ISC](https://www.isc.org/downloads/software-support-policy/isc-license/) |
| [pdfjs-dist](https://github.com/mozilla/pdfjs-dist) | 3.3.122 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [rxjs](https://github.com/reactivex/rxjs) | 7.8.1 | [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) |
| [tslib](https://github.com/Microsoft/tslib) | 2.8.1 | [0BSD](http://landley.net/toybox/license.html) |
| [zone.js](https://github.com/angular/angular) | 0.14.8 | [MIT](http://www.opensource.org/licenses/MIT) |

View File

@ -7,35 +7,36 @@ The purpose of this tutorial is to describe how to develop a “hello world” e
# Prerequisites
The starting point for this tutorial is the availability of the full repository of the [Alfresco Content Application (aka ACA)](https://github.com/Alfresco/alfresco-content-app "https://github.com/Alfresco/alfresco-content-app") on your development environment (your laptop as an example). This tutorial has been written with the following versions of the software:
- ACA version 5.3.0,
- ACS 23.4,
- NodeJs version 18.20.3
- ACA version 2.2.0,
- ACS 7.0.0-M3,
- NodeJs version 14.15.2,
- Chrome Version 87.0.4280.88.
# Creating the ACA extension
First create a folder where you would like to place the extensions. i.e. `/extensions`.
As described [here](https://github.com/Alfresco/alfresco-digital-workspace-app/blob/develop/docs/extending.md "https://github.com/Alfresco/alfresco-digital-workspace-app/blob/develop/docs/extending.md"), the creation of an ADW extension is straightforward following the [Nx Workspace](https://nx.dev/angular "https://nx.dev/angular") dev tools for monorepos.
Then run the `@nx/angular` library generator using the following command as a template:
```console
npx nx generate @nx/angular:library --name=@myorg/my-extension --buildable=true --directory=extensions/myextension --publishable=true --importPath=@myorg/my-extension --projectNameAndRootFormat=as-provided --no-interactive
```
From the root folder of the ACA project, launch the command below from a terminal. As you can see, with the command below you are going to create a new extension named `my-extension`.
where `name` is the name of the library, `directory` is a directory where the library is placed and `importPath` is the library name used for the import, like `@myorg/my-awesome-lib`. This must be a valid npm package name.
ng generate library my-extension
See the official [Nx Angular library](https://nx.dev/nx-api/angular/generators/library) documentation for more details.
In case of errors, add the following line to the `tsconfig.json` file.
Next to validate the changed verify the following:
"compilerOptions": { "baseUrl": ".", "rootDir": "." }
- Check in `tsconfig.base.json` that an import path exists and points to the correct entry point:
```json
"@myorg/my-extension": ["extensions/my-extension/src/index.ts"],
```
Once done, in the `projects/my-extension` path you will find the following structure:
- Test if npm i is working:
- `src` folder containing all the typescript source code. Very important is the `public-api.ts` file defining all the inclusions of the extension and the `lib/my-extension.module.ts` file defining the module class for the extension.
- README.md file for documentation purposes as well as other files used for testing and configuration.
To complete the creation, build the extension launching the following command.
nx build my-extension
# Developing the basics of the ACA extension
Now that the `my-extension` is created, let's add the proper configuration to the extension module. For this purpose, edit the `extensions/my-extension/src/lib/my-extension.module.ts` file changing what is described below.
Now that the `my-extension` is created, let's add the proper configuration to the extension module. For this purpose, edit the `projects/my-extension/src/lib/my-extension.module.ts` file changing what is described below.
```typescript
import { BrowserModule } from '@angular/platform-browser';
@ -59,8 +60,8 @@ export function components() {
provide: TRANSLATION_PROVIDER,
multi: true,
useValue: {
name: 'my-extension',
source: 'assets/my-extension',
name: 'adf-my-extension',
source: 'assets/adf-my-extension',
},
},
MyExtensionService,
@ -82,20 +83,17 @@ It's now time for the configuration of the brand new extension. For this purpose
To create the proper configuration, create the folder below in the described path.
extensions/my-extension/assets
projects/my-extension/assets
Once done, create the descriptor file `extensions/my-extension/assets/my-extension.json` file with the following content.
Please keep in mind that:
- The file name must be unique inside the application.
- Choose a name that does not conflict with other extensions.
- The descriptor file follows the schema in `extension.schema.json`
Once done, create the file `projects/my-extension/assets/my-extension.json` file with the following content.
```json
{
"$id": "my-extension-id",
"$schema": "../../../extension.schema.json",
"$id": "my-extension",
"$version": "1.0.0",
"$vendor": "Your name or company name",
"$name": "your plugin name",
"$name": "plugin1",
"$description": "demo plugin",
"$license": "MIT",
@ -165,7 +163,7 @@ Last but not least, edit the package.json file to allow the build of the extensi
{ ...
"scripts": {
...,
"build:my-extension": "nx build my-extension && npx cpr extensions/my-extension/assets dist/my-extension/assets --deleteFirst"
"build:my-extension": "nx build my-extension && npx cpr projects/my-extension/assets dist/my-extension/assets --deleteFirst"
}, ...
}

View File

@ -26,7 +26,7 @@ In this tutorial, we are going to implement the following features:
In order to learn more about :
-The search UI configuration possibilities refer to the [ADF Search configuration documentation](https://github.com/Alfresco/alfresco-ng2-components/blob/develop/docs/user-guide/search-configuration-guide.md)
-The search Query configuration possibilities refer to the [Full text search reference documentation](https://support.hyland.com/r/Alfresco/Alfresco-Search-Services/2.0/Alfresco-Search-Services/Using/Full-text-search-reference)
-The search Query configuration possibilities refer to the [Full text search reference documentation](https://docs.alfresco.com/search-services/latest/using/)
### Add a new search form

View File

@ -1,3 +1,3 @@
{
"XAT-4370" : "https://hyland.atlassian.net/browse/ACS-5479"
"C213097" : "https://hyland.atlassian.net/browse/ACS-5479"
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -43,7 +43,7 @@ test.describe('Create folders', () => {
await apiClientFactory.loginUser(sessionTestUser);
});
test('[XAT-17773] Should close opened dialogs on session expire', async ({ loginPage, personalFiles }) => {
test('[C286473] should close opened dialogs on session expire', async ({ loginPage, personalFiles }) => {
await loginPage.navigate();
await loginPage.loginUser({ username: sessionTestUser.username, password: sessionTestUser.password });
const folderDialog = personalFiles.folderDialog;

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -59,7 +59,7 @@ test.describe('viewer file', () => {
});
test.describe('general tests', () => {
test('[XAT-4366] login page layout', async ({ loginPage }) => {
test('[C213089] login page layout', async ({ loginPage }) => {
await loginPage.navigate();
await expect(loginPage.username, 'username input is not enabled').toBeEnabled();
await expect(loginPage.password, 'password input is not enabled').toBeEnabled();
@ -72,20 +72,20 @@ test.describe('viewer file', () => {
});
test.describe('with invalid credentials', () => {
test('[XAT-4378] unauthenticated user is redirected to Login page', async ({ personalFiles }) => {
test('[C213106] unauthenticated user is redirected to Login page', async ({ personalFiles }) => {
await personalFiles.navigate();
expect(personalFiles.page.url()).toContain('login');
});
});
test.describe('with valid credentials', () => {
test('[XAT-4370] Login with a user that contains non-Latin characters in username or password', async ({ loginPage }) => {
test('[C213097] logs in with user with non-latin characters', async ({ loginPage }) => {
await loginPage.navigate();
await loginPage.loginUser({ username: otherLanguageUser.username, password: otherLanguageUser.password });
expect(loginPage.page.url()).toContain('personal-files');
});
test('[XAT-17774] Redirects to Home Page when navigating to the Login page while already logged in', async ({ loginPage }) => {
test('[C213107] redirects to Home Page when navigating to the Login page while already logged in', async ({ loginPage }) => {
const { username } = johnDoe;
await loginPage.navigate();
await loginPage.loginUser({ username: username, password: username });
@ -95,7 +95,7 @@ test.describe('viewer file', () => {
expect(loginPage.page.url()).toContain('personal-files');
});
test('[XAT-4372] Login with a user that has changed its password', async ({ loginPage }) => {
test('[C213104] user is able to login after changing his password', async ({ loginPage }) => {
await apiClientFactory.changePassword(testUser2.username, newPassword);
await loginPage.navigate();
await loginPage.loginUser({ username: testUser2.username, password: newPassword });

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -37,7 +37,7 @@ test.describe('viewer file', () => {
await apiClientFactory.createUser(testUser);
});
test('[XAT-4382] User is not signed back in when pressing browser Back button after sign out', async ({ loginPage }) => {
test('[C213145] redirects to Login page when pressing browser Back after logout', async ({ loginPage }) => {
await loginPage.navigate();
await loginPage.loginUser({ username: testUser.username, password: testUser.password });
await loginPage.logoutUser();

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -82,7 +82,7 @@ test.describe('Copy actions', () => {
}
};
test('[XAT-4941] Copy a file', async ({ personalFiles }) => {
test('[C217135] Copy a file', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
@ -91,7 +91,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4942] Copy a folder with content', async ({ personalFiles }) => {
test('[C291888] Copy a folder with content', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
@ -103,7 +103,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
});
test('[XAT-4943] Copy multiple items', async ({ personalFiles }) => {
test('[C291889] Copy multiple items', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
await copyContentInPersonalFiles(personalFiles, [sourceFolder, sourceFile], destinationFolder);
expect.soft(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeTruthy();
@ -115,7 +115,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4944] Copy a file with a name that already exists on the destination', async ({ personalFiles }) => {
test('[C217137] Copy a file with a name that already exists on the destination', async ({ personalFiles }) => {
await nodesApi.createFile(sourceFile, destinationFolderId);
const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
@ -127,7 +127,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeTruthy();
});
test('[XAT-4945] Copy a folder with a name that already exists on the destination', async ({ personalFiles }) => {
test('[C217138] Copy a folder with a name that already exists on the destination', async ({ personalFiles }) => {
const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');
@ -143,7 +143,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeTruthy();
});
test('[XAT-4947] Copy locked file', async ({ personalFiles }) => {
test('[C217139] Copy locked file', async ({ personalFiles }) => {
const lockType = 'ALLOW_OWNER_CHANGES';
await nodesApi.lockNodes([sourceFileId], lockType);
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
@ -154,7 +154,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4948] Copy folder that contains locked file', async ({ personalFiles }) => {
test('[C217140] Copy folder that contains locked file', async ({ personalFiles }) => {
const lockType = 'ALLOW_OWNER_CHANGES';
await nodesApi.lockNodes([sourceFileInsideFolderId], lockType);
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
@ -168,7 +168,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFileInsideFolder)).toBeTruthy();
});
test('[XAT-4949] Undo copy of files', async ({ personalFiles }) => {
test('[C217171] Undo copy of files', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
await copyContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
await personalFiles.snackBar.actionButton.click();
@ -178,7 +178,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeFalsy();
});
test('[XAT-4950] Undo copy of folders', async ({ personalFiles }) => {
test('[C217172] Undo copy of folders', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
await copyContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
await personalFiles.snackBar.actionButton.click();
@ -188,7 +188,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFolder)).toBeFalsy();
});
test('[XAT-4951] Undo copy of a file when a file with same name already exists on the destination', async ({ personalFiles }) => {
test('[C217173] Undo copy of a file when a file with same name already exists on the destination', async ({ personalFiles }) => {
await nodesApi.createFile(sourceFile, destinationFolderId);
const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
@ -201,7 +201,7 @@ test.describe('Copy actions', () => {
expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
});
test('[XAT-4952] Undo copy of a folder when a folder with same name already exists on the destination', async ({ personalFiles }) => {
test('[C217174] Undo copy of a folder when a folder with same name already exists on the destination', async ({ personalFiles }) => {
const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -79,21 +79,21 @@ test.describe('Copy Move actions', () => {
await myLibrariesPage.contentNodeSelector.selectDestination(destinationFolder);
};
test('[XAT-4922] Consumer user cannot select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
test('[C263876] Consumer user cannot select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
await loginPage.loginUser({ username: consumerUser, password: consumerUser }, { withNavigation: true, waitForLoading: true });
await myLibrariesPage.navigate();
await copyContentInMyLibraries(myLibrariesPage);
await expect(myLibrariesPage.contentNodeSelector.actionButton).toBeDisabled();
});
test('[XAT-4923] Contributor user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
test('[C263877] Contributor user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
await loginPage.loginUser({ username: contributorUser, password: contributorUser }, { withNavigation: true, waitForLoading: true });
await myLibrariesPage.navigate();
await copyContentInMyLibraries(myLibrariesPage);
await expect(myLibrariesPage.contentNodeSelector.actionButton).toBeEnabled();
});
test('[XAT-4924] Collaborator user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
test('[C263878] Collaborator user can select the folder as destination', async ({ loginPage, myLibrariesPage }) => {
await loginPage.loginUser({ username: collaboratorUser, password: collaboratorUser }, { withNavigation: true, waitForLoading: true });
await myLibrariesPage.navigate();
await copyContentInMyLibraries(myLibrariesPage);

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -74,7 +74,7 @@ test.describe('Move actions', () => {
await personalFilesPage.spinner.waitForReload();
};
test('[XAT-4996] Move a file', async ({ personalFiles }) => {
test('[C217316] Move a file', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
const msg = await personalFiles.snackBar.message.innerText();
@ -85,7 +85,7 @@ test.describe('Move actions', () => {
expect(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4998] Move multiple items', async ({ personalFiles }) => {
test('[C291958] Move multiple items', async ({ personalFiles }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
await moveContentInPersonalFiles(personalFiles, [sourceFolder, sourceFile], destinationFolder);
const msg = await personalFiles.snackBar.message.innerText();
@ -98,7 +98,7 @@ test.describe('Move actions', () => {
expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4999] Move a file with a name that already exists on the destination', async ({ personalFiles }) => {
test('[C217318] Move a file with a name that already exists on the destination', async ({ personalFiles }) => {
await nodesApi.createFile(sourceFile, destinationFolderId);
const expectedNameForCopiedFile = sourceFile.replace('.', '-1.');
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
@ -112,7 +112,7 @@ test.describe('Move actions', () => {
expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
});
test('[XAT-5000] Move a folder with a name that already exists on the destination', async ({ personalFiles }) => {
test('[C217319] Move a folder with a name that already exists on the destination', async ({ personalFiles }) => {
const existingFolderId = (await nodesApi.createFolder(sourceFolder, destinationFolderId)).entry.id;
await nodesApi.createFile(sourceFileInsideFolder, existingFolderId);
const expectedNameForCopiedFile = sourceFileInsideFolder.replace('.', '-1.');
@ -129,7 +129,7 @@ test.describe('Move actions', () => {
expect(await personalFiles.dataTable.isItemPresent(expectedNameForCopiedFile)).toBeFalsy();
});
test('[XAT-4989] Move locked file', async ({ personalFiles }) => {
test('[C217320] Move locked file', async ({ personalFiles }) => {
const lockType = 'ALLOW_OWNER_CHANGES';
await nodesApi.lockNodes([sourceFileId], lockType);
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
@ -142,7 +142,7 @@ test.describe('Move actions', () => {
expect.soft(await personalFiles.dataTable.isItemPresent(sourceFile)).toBeTruthy();
});
test('[XAT-4992] Undo move files', async ({ personalFiles, trashPage }) => {
test('[C217324] Undo move files', async ({ personalFiles, trashPage }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFile);
await moveContentInPersonalFiles(personalFiles, [sourceFile], destinationFolder);
await personalFiles.snackBar.actionButton.click();
@ -154,7 +154,7 @@ test.describe('Move actions', () => {
expect(await trashPage.dataTable.isItemPresent(sourceFile)).toBeFalsy();
});
test('[XAT-4993] Undo move folder', async ({ personalFiles, trashPage }) => {
test('[C217325] Undo move of folders', async ({ personalFiles, trashPage }) => {
await Utils.reloadPageIfRowNotVisible(personalFiles, sourceFolder);
await moveContentInPersonalFiles(personalFiles, [sourceFolder], destinationFolder);
await personalFiles.snackBar.actionButton.click();
@ -185,12 +185,12 @@ test.describe('Move actions', () => {
[
{
id: 'XAT-4997',
id: 'C217317',
testTitle: `Move a folder with content`,
lockedFile: false
},
{
id: 'XAT-4990',
id: 'C217321',
testTitle: 'Move folder that contains locked file',
lockedFile: true
}

View File

@ -1 +1,48 @@
{}
{
"C325043": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325044": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325045": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325047": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325031": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325032": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325033": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325030": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325026": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325042": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325147": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325148": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325149": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325150": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325153": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325151": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325139": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325143": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325144": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325145": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325146": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325157": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325154": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325158": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325161": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325142": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325141": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325140": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325156": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325155": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325162": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325163": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325050": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325048": "https://alfresco.atlassian.net/browse/ACS-6412",
"C216339": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325020": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325034": "https://alfresco.atlassian.net/browse/ACS-6412",
"C290146": "https://alfresco.atlassian.net/browse/ACS-6412",
"C290142": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325028": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325027": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325023": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325024": "https://alfresco.atlassian.net/browse/ACS-6412",
"C325025": "https://alfresco.atlassian.net/browse/ACS-6412"
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -51,7 +51,7 @@ test.describe('Create file from template', () => {
let fileLink: string;
const selectDialogTitle = 'Select a document template';
const dialogBreadcrumb = 'Node Templates';
const nameLabel = 'Name';
const nameLabel = 'Name *';
const titleLabel = 'Title';
const descriptionLabel = 'Description';
const emptyString = '';
@ -138,7 +138,7 @@ test.describe('Create file from template', () => {
});
test.describe('Select Template dialog', () => {
test('[XAT-5229] Select template - dialog UI - when no templates exist in the repo', async () => {
test('[C325043] Select template - dialog UI - with existing templates', async () => {
await expect.soft(selectFileTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await expect.soft(selectFileTemplateDialog.getBreadcrumb(dialogBreadcrumb)).toBeVisible();
await expect.soft(dataTable.getRowByName(templatesFolder1)).not.toBeEmpty();
@ -149,13 +149,13 @@ test.describe('Create file from template', () => {
await expect(selectFileTemplateDialog.actionButton).toBeDisabled();
});
test(`[XAT-5231] Templates don't appear if user doesn't have permissions to see them`, async () => {
test(`[C325044] Templates don't appear if user doesn't have permissions to see them`, async () => {
await expect(selectFileTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await expect(dataTable.getRowByName(restrictedTemplateFolder)).toBeHidden();
await expect(dataTable.getRowByName(templateInRestrictedFolder)).toBeHidden();
});
test(`[XAT-5232] Navigate through the templates list with folder hierarchy`, async () => {
test(`[C325045] Navigate through the templates list with folder hierarchy`, async () => {
await expect(selectFileTemplateDialog.getBreadcrumb(dialogBreadcrumb)).toBeVisible();
await expect(dataTable.getRowByName(templatesFolder1)).toBeVisible();
await expect(dataTable.getRowByName(templatesFolder2)).toBeVisible();
@ -175,7 +175,7 @@ test.describe('Create file from template', () => {
await expect(selectFileTemplateDialog.getOptionLocator(dialogBreadcrumb)).toBeVisible();
});
test(`[XAT-5233] Templates list doesn't allow multiple selection`, async () => {
test(`[C325047] Templates list doesn't allow multiple selection`, async () => {
await expect(dataTable.getSelectedRow).toHaveCount(0);
await dataTable.getRowByName(template1InRoot).click({ modifiers: [commandKey] });
@ -188,20 +188,20 @@ test.describe('Create file from template', () => {
await expect(dataTable.getSelectedRow).toContainText(template2InRoot);
});
test('[XAT-5235] Links to files are not displayed', async () => {
test('[C325050] Links to files are not displayed', async () => {
await expect(dataTable.getRowByName(template1InRoot)).toBeVisible();
await expect(dataTable.getRowByName(template2InRoot)).toBeVisible();
await expect(dataTable.getRowByName(fileLink)).toBeHidden();
});
test('[XAT-5236] Cancel the Select template dialog', async () => {
test('[C325048] Cancel the Select template dialog', async () => {
await expect(selectFileTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await selectFileTemplateDialog.cancelButton.click();
await expect(selectFileTemplateDialog.getDialogTitle(selectDialogTitle)).toBeHidden();
});
test('[XAT-5234] Select Template - Next button is disabled when selecting a folder', async () => {
test('[C216339] Next button is disabled when selecting a folder', async () => {
await expect(dataTable.getRowByName(templatesFolder1)).toBeVisible();
await expect(selectFileTemplateDialog.actionButton).toBeDisabled();
@ -225,7 +225,7 @@ test.describe('Create file from template', () => {
}
});
test('[XAT-5237] Create file from template - dialog UI', async () => {
test('[C325020] Create file from template - dialog UI', async () => {
await expect.soft(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await expect.soft(createFileFromTemplateDialog.getDialogLabel(nameLabel)).toBeVisible();
await expect.soft(createFileFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(template1InRoot);
@ -237,7 +237,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeEnabled();
});
test('[XAT-5238] File name is required', async () => {
test('[C325031] File name is required', async () => {
await expect(createFileFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(template1InRoot);
await createFileFromTemplateDialog.getDialogLabel(nameLabel).clear();
@ -249,7 +249,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5239] Special characters in file name', async () => {
test('[C325032] Special characters in file name', async () => {
const nameWithSpecialChars = ['a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a'];
for (const specialFileName of nameWithSpecialChars) {
@ -266,8 +266,8 @@ test.describe('Create file from template', () => {
}
});
test('[XAT-5240] File name ending with a dot', async () => {
await createFileFromTemplateDialog.getDialogLabel(nameLabel).fill(template1InRoot + dotString);
test('[C325033] File name ending with a dot', async () => {
await createFileFromTemplateDialog.getDialogLabel(nameLabel).fill(dotString);
await createFileFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFileFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(template1InRoot + dotString);
expect
@ -276,7 +276,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5241] File name containing only spaces', async () => {
test('[C325034] File name containing only spaces', async () => {
await createFileFromTemplateDialog.getDialogLabel(nameLabel).clear();
await createFileFromTemplateDialog.getDialogLabel(nameLabel).fill(spaceString);
await createFileFromTemplateDialog.page.keyboard.press(tabKeyString);
@ -290,7 +290,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5243] File title too long', async () => {
test('[C290146] File title too long', async () => {
await createFileFromTemplateDialog.getDialogLabel(titleLabel).fill(Utils.string257Long);
await createFileFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFileFromTemplateDialog.getDialogLabel(titleLabel)).toHaveValue(Utils.string257Long);
@ -300,7 +300,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5242] Description too long', async () => {
test('[C290142] Description too long', async () => {
await createFileFromTemplateDialog.getDialogLabel(descriptionLabel).fill(Utils.string513Long);
await createFileFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFileFromTemplateDialog.getDialogLabel(descriptionLabel)).toHaveValue(Utils.string513Long);
@ -313,7 +313,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5246] Create a file with a duplicate name', async ({ personalFiles }) => {
test('[C325028] Create a file with a duplicate name', async ({ personalFiles }) => {
const snackBar = personalFiles.snackBar;
await createFileFromTemplateDialog.createFromTemplateAction(commonFileName);
@ -321,7 +321,7 @@ test.describe('Create file from template', () => {
await expect(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
});
test('[XAT-5247] Cancel file creation', async () => {
test('[C325027] Cancel file creation', async () => {
await expect(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await createFileFromTemplateDialog.cancelButton.click();
await expect(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeHidden();
@ -342,19 +342,19 @@ test.describe('Create file from template', () => {
}
});
test('[XAT-5244] Create a file from a template - with a new Name', async () => {
test('[C325030] Create a file from a template - with a new Name', async () => {
await createFileFromTemplateDialog.createFromTemplateAction(randomFileName);
await dataTable.goThroughPagesLookingForRowWithName(randomFileName);
await expect(dataTable.getRowByName(randomFileName)).toBeVisible();
});
test('[XAT-5245] Create a file from a template - with a Name, Title and Description', async () => {
test('[C325026] Create a file from a template - with a Name, Title and Description', async () => {
await createFileFromTemplateDialog.createFromTemplateAction(randomFileName, randomFileTitle, randomFileDescription);
await dataTable.goThroughPagesLookingForRowWithName(randomFileName);
await expect(dataTable.getCellLinkByName(randomFileName)).toHaveAttribute(titleLabel, randomFileTitle + `\n` + randomFileDescription);
});
test('[XAT-5248] Trim spaces from file Name', async () => {
test('[C325042] Trim spaces from file Name', async () => {
await createFileFromTemplateDialog.createFromTemplateAction(' ' + randomFileName + ' ');
await dataTable.goThroughPagesLookingForRowWithName(randomFileName);
await expect(dataTable.getRowByName(randomFileName)).toBeVisible();
@ -362,7 +362,7 @@ test.describe('Create file from template', () => {
});
});
test.describe('File created from template on Libraries', () => {
test.describe('File created from template on Personal Files Libraries', () => {
const randomLibraryName = `playwright-library-c2-${Utils.random()}`;
let sitesApi: SitesApi;
@ -390,7 +390,7 @@ test.describe('Create file from template', () => {
await dataTable.getRowByName(template1InRoot).click();
await selectFileTemplateDialog.actionButton.click();
} catch (error) {
console.error(`File created from template on Libraries, beforeEach failed: ${error}`);
console.error(`File created from template on Personal Files Libraries, beforeEach failed: ${error}`);
}
});
@ -398,19 +398,19 @@ test.describe('Create file from template', () => {
await sitesApi.deleteSites([randomLibraryName]);
});
test('[XAT-5249] Create a file from a template from library - with Name, Title and Description', async () => {
test('[C325023] Create a file from a template from library - with Name, Title and Description', async () => {
await createFileFromTemplateDialog.createFromTemplateAction(randomFileName, randomFileTitle, randomFileDescription);
await expect(dataTable.getCellLinkByName(randomFileName)).toHaveAttribute(titleLabel, randomFileTitle + `\n` + randomFileDescription);
});
test('[XAT-5250] Cancel file creation in a library', async () => {
test('[C325024] Cancel file creation in a library', async () => {
await expect(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await createFileFromTemplateDialog.cancelButton.click();
await expect(createFileFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeHidden();
await expect(dataTable.getRowByName(randomFileName)).toBeHidden();
});
test('[XAT-5251] Create a file with a duplicate name in a library', async ({ myLibrariesPage }) => {
test('[C325025] Create a file with a duplicate name in a library', async ({ myLibrariesPage }) => {
const snackBar = myLibrariesPage.snackBar;
await createFileFromTemplateDialog.createFromTemplateAction(commonFileName);

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -52,7 +52,7 @@ test.describe('Create folder from template', () => {
let folderLink: string;
const selectDialogTitle = 'Select a folder template';
const dialogBreadcrumb = 'Space Templates';
const nameLabel = 'Name';
const nameLabel = 'Name *';
const titleLabel = 'Title';
const descriptionLabel = 'Description';
const emptyString = '';
@ -165,7 +165,7 @@ test.describe('Create folder from template', () => {
});
test.describe('Select Template dialog', () => {
test('[XAT-5252] Select template - dialog UI - with existing templates', async () => {
test('[C325147] Select template - dialog UI - with existing templates', async () => {
await expect.soft(selectFolderTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await expect.soft(selectFolderTemplateDialog.getBreadcrumb(dialogBreadcrumb)).toBeVisible();
await expect.soft(dataTable.getRowByName(templateFolder1)).not.toBeEmpty();
@ -176,12 +176,12 @@ test.describe('Create folder from template', () => {
await expect(selectFolderTemplateDialog.actionButton).toBeDisabled();
});
test(`[XAT-5253] Templates don't appear if user doesn't have permissions to see them`, async () => {
test(`[C325148] Templates don't appear if user doesn't have permissions to see them`, async () => {
await expect(selectFolderTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await expect(dataTable.getRowByName(restrictedTemplateFolder)).toBeHidden();
});
test(`[XAT-5254] Navigate through the templates list with folder hierarchy`, async () => {
test(`[C325149] Navigate through the templates list with folder hierarchy`, async () => {
await expect(selectFolderTemplateDialog.getBreadcrumb(dialogBreadcrumb)).toBeVisible();
await expect(dataTable.getRowByName(templateFolder1)).toBeVisible();
@ -199,7 +199,7 @@ test.describe('Create folder from template', () => {
await expect(selectFolderTemplateDialog.getOptionLocator(dialogBreadcrumb)).toBeVisible();
});
test(`[XAT-5255] Templates list doesn't allow multiple selection`, async () => {
test(`[C325150] Templates list doesn't allow multiple selection`, async () => {
await expect(dataTable.getSelectedRow).toHaveCount(0);
await dataTable.getRowByName(templateFolder1).click({ modifiers: [commandKey] });
@ -212,19 +212,19 @@ test.describe('Create folder from template', () => {
await expect(dataTable.getSelectedRow).toContainText(templateFolder2);
});
test('[XAT-5257] Links to folders are not displayed', async () => {
test('[C325153] Links to folders are not displayed', async () => {
await expect(dataTable.getRowByName(templateFolder1)).toBeVisible();
await expect(dataTable.getRowByName(folderLink)).toBeHidden();
});
test('[XAT-5258] Cancel the Select template dialog', async () => {
test('[C325151] Cancel the Select template dialog', async () => {
await expect(selectFolderTemplateDialog.getDialogTitle(selectDialogTitle)).toBeVisible();
await selectFolderTemplateDialog.cancelButton.click();
await expect(selectFolderTemplateDialog.getDialogTitle(selectDialogTitle)).toBeHidden();
});
test('[XAT-5256] Select Template - Next button is disabled when selecting a file', async () => {
test('[C325139] Next button is disabled when selecting a file', async () => {
await expect(dataTable.getRowByName(fileInRootFolder)).toBeVisible();
await expect(selectFolderTemplateDialog.actionButton).toBeDisabled();
@ -252,7 +252,7 @@ test.describe('Create folder from template', () => {
}
});
test('[XAT-5259] Create folder from template - dialog UI', async () => {
test('[C325142] Create folder from template - dialog UI', async () => {
await expect.soft(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await expect.soft(createFolderFromTemplateDialog.getDialogLabel(nameLabel)).toBeVisible();
await expect.soft(createFolderFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(templateFolder1);
@ -264,7 +264,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeEnabled();
});
test('[XAT-5260] Folder name is required', async () => {
test('[C325143] Folder name is required', async () => {
await expect(createFolderFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(templateFolder1);
await createFolderFromTemplateDialog.getDialogLabel(nameLabel).clear();
@ -276,7 +276,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5261] Special characters in folder name', async () => {
test('[C325144] Special characters in folder name', async () => {
const nameWithSpecialChars = ['a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a'];
for (const specialFolderName of nameWithSpecialChars) {
@ -293,8 +293,8 @@ test.describe('Create folder from template', () => {
}
});
test('[XAT-5262] Folder name ending with a dot', async () => {
await createFolderFromTemplateDialog.getDialogLabel(nameLabel).fill(templateFolder1 + dotString);
test('[C325145] Folder name ending with a dot', async () => {
await createFolderFromTemplateDialog.getDialogLabel(nameLabel).fill(dotString);
await createFolderFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFolderFromTemplateDialog.getDialogLabel(nameLabel)).toHaveValue(templateFolder1 + dotString);
expect
@ -303,7 +303,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5263] Folder name containing only spaces', async () => {
test('[C325146] Folder name containing only spaces', async () => {
await createFolderFromTemplateDialog.getDialogLabel(nameLabel).clear();
await createFolderFromTemplateDialog.getDialogLabel(nameLabel).fill(spaceString);
await createFolderFromTemplateDialog.page.keyboard.press(tabKeyString);
@ -317,7 +317,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5265] Folder title too long', async () => {
test('[C325141] Title too long', async () => {
await createFolderFromTemplateDialog.getDialogLabel(titleLabel).fill(Utils.string257Long);
await createFolderFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFolderFromTemplateDialog.getDialogLabel(titleLabel)).toHaveValue(Utils.string257Long);
@ -327,7 +327,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5264] Folder description too long', async () => {
test('[C325140] Description too long', async () => {
await createFolderFromTemplateDialog.getDialogLabel(descriptionLabel).fill(Utils.string513Long);
await createFolderFromTemplateDialog.page.keyboard.press(tabKeyString);
await expect(createFolderFromTemplateDialog.getDialogLabel(descriptionLabel)).toHaveValue(Utils.string513Long);
@ -340,7 +340,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.createButton).toBeDisabled();
});
test('[XAT-5268] Create a folder with a duplicate name', async ({ personalFiles }) => {
test('[C325156] Create a folder with a duplicate name', async ({ personalFiles }) => {
const snackBar = personalFiles.snackBar;
await createFolderFromTemplateDialog.createFromTemplateAction(commonFolderName);
@ -348,7 +348,7 @@ test.describe('Create folder from template', () => {
await expect(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
});
test('[XAT-5269] Cancel folder creation', async () => {
test('[C325155] Cancel folder creation', async () => {
await expect(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await createFolderFromTemplateDialog.cancelButton.click();
await expect(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeHidden();
@ -369,7 +369,7 @@ test.describe('Create folder from template', () => {
}
});
test('[XAT-5266] Create a folder from a template - with a new Name', async () => {
test('[C325157] Create a folder from a template - with a new Name', async () => {
await createFolderFromTemplateDialog.createFromTemplateAction(randomFolderName);
await dataTable.goThroughPagesLookingForRowWithName(randomFolderName);
await expect(dataTable.getRowByName(randomFolderName)).toBeVisible();
@ -379,13 +379,13 @@ test.describe('Create folder from template', () => {
await expect(dataTable.getRowByName(fileInFolder1)).toBeVisible();
});
test('[XAT-5267] Create a folder from a template - with a Name, Title and Description', async () => {
test('[C325154] Create a folder from a template - with a Name, Title and Description', async () => {
await createFolderFromTemplateDialog.createFromTemplateAction(randomFolderName, randomFolderTitle, randomFolderDescription);
await dataTable.goThroughPagesLookingForRowWithName(randomFolderName);
await expect(dataTable.getCellLinkByName(randomFolderName)).toHaveAttribute(titleLabel, randomFolderTitle + `\n` + randomFolderDescription);
});
test('[XAT-5270] Trim spaces from folder Name', async () => {
test('[C325158] Trim spaces from folder Name', async () => {
await createFolderFromTemplateDialog.createFromTemplateAction(' ' + randomFolderName + ' ');
await dataTable.goThroughPagesLookingForRowWithName(randomFolderName);
await expect(dataTable.getRowByName(randomFolderName)).toBeVisible();
@ -393,7 +393,7 @@ test.describe('Create folder from template', () => {
});
});
test.describe('Folder created from template on Libraries', () => {
test.describe('Folder created from template on Personal Files Libraries', () => {
const randomLibraryName = `playwright-library-c1-${Utils.random()}`;
let sitesApi: SitesApi;
@ -404,7 +404,7 @@ test.describe('Create folder from template', () => {
const libraryGuId = await sitesApi.getDocLibId(randomLibraryName);
await nodesApi.createFolder(commonFolderName, libraryGuId);
} catch (error) {
console.error(`Folder created from template on Libraries, beforeAll failed : ${error}`);
console.error(`Folder created from template on Personal Files Libraries, beforeAll failed : ${error}`);
}
});
@ -438,7 +438,7 @@ test.describe('Create folder from template', () => {
}
});
test('[XAT-5271] Create a folder from a template from library - with Name, Title and Description', async () => {
test('[C325161] Create a folder from a template from library - with Name, Title and Description', async () => {
await createFolderFromTemplateDialog.createFromTemplateAction(randomFolderName, randomFolderTitle, randomFolderDescription);
await expect
.soft(dataTable.getCellLinkByName(randomFolderName))
@ -449,14 +449,14 @@ test.describe('Create folder from template', () => {
await expect(dataTable.getRowByName(fileInFolder1)).toBeVisible();
});
test('[XAT-5272] Cancel folder creation in a library', async () => {
test('[C325162] Cancel folder creation in a library', async () => {
await expect(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeVisible();
await createFolderFromTemplateDialog.cancelButton.click();
await expect(createFolderFromTemplateDialog.getDialogTitle(createDialogTitle)).toBeHidden();
await expect(dataTable.getRowByName(randomFolderName)).toBeHidden();
});
test('[XAT-5273] Create a folder with a duplicate name in a library', async ({ myLibrariesPage }) => {
test('[C325163] Create a folder with a duplicate name in a library', async ({ myLibrariesPage }) => {
const snackBar = myLibrariesPage.snackBar;
await createFolderFromTemplateDialog.createFromTemplateAction(commonFolderName);

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -48,7 +48,6 @@ test.describe('Create folders', () => {
const createNewFolderString = 'Create new folder';
const spacesString = ' ';
const commonFolderName = `create-folder-${Utils.random()}`;
const newFolderName = `new-folder-${Utils.random()}`;
const username = `user-${Utils.random()}`;
test.beforeAll(async () => {
@ -78,7 +77,7 @@ test.describe('Create folders', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5078] Create new folder dialog UI check', async () => {
test('[C216345] Create new folder dialog check', async () => {
await expect(folderDialog.getLabelText('Name')).toBeVisible();
await expect(folderDialog.getRequiredMarker('Name')).toBeVisible();
await expect(folderDialog.folderNameInputLocator).toBeVisible();
@ -90,7 +89,7 @@ test.describe('Create folders', () => {
await expect(folderDialog.createButton).toBeDisabled();
});
test('[XAT-5079] Create a folder without a name - Disabled Create button', async () => {
test('[C216346] Create a folder without a name', async () => {
await folderDialog.folderNameInputLocator.fill(randomFolderName);
await expect(folderDialog.folderNameInputLocator).toHaveValue(randomFolderName);
await expect(folderDialog.createButton).toBeEnabled();
@ -102,14 +101,14 @@ test.describe('Create folders', () => {
await expect(folderDialog.createButton).toBeDisabled();
});
test('[XAT-5081] Create folder when a name that ends with a dot "."', async () => {
test('[C216348] Create folder when a name that ends with a dot "."', async () => {
await folderDialog.folderNameInputLocator.fill(randomFolderName + '.');
await expect(folderDialog.createButton).toBeDisabled();
await expect(folderDialog.folderNameInputHint).toContainText(errorStrings.folderNameCantEndWithAPeriod);
});
test('[XAT-5080] Create folder with a name containing special characters', async () => {
test('[C216347] Create folder with a name containing special characters', async () => {
const namesWithSpecialChars = ['a*a', 'a"a', 'a<a', 'a>a', `a\\a`, 'a/a', 'a?a', 'a:a', 'a|a'];
for (const folderName of namesWithSpecialChars) {
await folderDialog.folderNameInputLocator.fill(folderName);
@ -119,21 +118,21 @@ test.describe('Create folders', () => {
}
});
test('[XAT-5082] Create a folder with a name containing only spaces', async () => {
test('[C280406] Create a folder with a name containing only spaces', async () => {
await folderDialog.folderNameInputLocator.fill(spacesString);
await expect(folderDialog.createButton).toBeDisabled();
await expect(folderDialog.folderNameInputHint).toContainText(errorStrings.folderNameCantContainOnlySpaces);
});
test('[XAT-5083] Cancel folder creation', async ({ personalFiles }) => {
test('[C216349] Cancel folder creation', async ({ personalFiles }) => {
await expect(personalFiles.page.getByRole(dialogString, { name: createNewFolderString })).toBeVisible();
await folderDialog.folderNameInputLocator.fill(randomFolderName);
await folderDialog.cancelButton.click();
await expect(personalFiles.page.getByRole(dialogString, { name: createNewFolderString })).toBeHidden();
});
test('[XAT-5084] Duplicate folder name error', async ({ personalFiles }) => {
test('[C216350] Duplicate folder name error', async ({ personalFiles }) => {
const folderSnackBar = personalFiles.snackBar;
await folderDialog.createNewFolderDialog(commonFolderName);
@ -146,30 +145,22 @@ test.describe('Create folders', () => {
folderTable = personalFiles.dataTable;
});
test('[XAT-5077] Create folder when pressing OK - with name and no description', async () => {
test('[C216341] Create a folder with name only', async () => {
await folderDialog.createNewFolderDialog(randomFolderName);
await expect(folderTable.getRowByName(randomFolderName)).toBeVisible();
});
test('[XAT-5076] Create folder when pressing OK - with name, title and description', async () => {
test('[C216340] Create a folder with name, title and description', async () => {
await folderDialog.createNewFolderDialog(randomFolderName, randomFolderTitle, randomFolderDescription);
await expect(folderTable.getCellLinkByName(randomFolderName)).toHaveAttribute('title', randomFolderTitle + `\n` + randomFolderDescription);
});
test('[XAT-5085] Folder created after trimmed ending spaces from a folder name', async () => {
test('[C216351] Folder created after trimmed ending spaces from a folder name', async () => {
await folderDialog.createNewFolderDialog(randomFolderName + spacesString);
await expect(folderTable.getRowByName(randomFolderName)).toBeVisible();
});
test('[XAT-17591] Duplicate folder name - can create folder with a new name', async ({ personalFiles }) => {
const folderSnackBar = personalFiles.snackBar;
await folderDialog.createNewFolderDialog(commonFolderName);
await expect(folderSnackBar.getByMessageLocator(errorStrings.thereIsAlreadyAFolderWithThisName)).toBeVisible();
await folderDialog.createNewFolderDialog(newFolderName);
await expect(folderTable.getRowByName(newFolderName)).toBeVisible();
});
});
});

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -94,7 +94,7 @@ test.describe('Create Libraries ', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed', sitesApi, createdLibrariesIds);
});
test('[XAT-5118] Create Library dialog UI check', async () => {
test('[C280024] Create Library dialog UI', async () => {
await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeVisible();
await expect(libraryDialog.getLabelText(libraryNameLabel)).toBeVisible();
await expect(libraryDialog.getRequiredMarker(libraryNameLabel)).toBeVisible();
@ -115,7 +115,7 @@ test.describe('Create Libraries ', () => {
libraryBreadcrumb = myLibrariesPage.breadcrumb;
});
test('[XAT-5119] Create a public library', async ({ myLibrariesPage }) => {
test('[C280025] Create a public library', async ({ myLibrariesPage }) => {
await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName);
await expect(libraryDialog.getLabelText(libraryNameLabel)).toHaveValue(randomLibraryName);
await expect(libraryDialog.getLabelText(libraryIdLabel)).toHaveValue(randomLibraryName);
@ -128,7 +128,7 @@ test.describe('Create Libraries ', () => {
createdLibrariesIds.push(randomLibraryName);
});
test('[XAT-5120] Create a moderated library', async ({ myLibrariesPage }) => {
test('[C289880] Create a moderated library', async ({ myLibrariesPage }) => {
await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, moderatedVisibility);
await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible();
@ -139,7 +139,7 @@ test.describe('Create Libraries ', () => {
createdLibrariesIds.push(randomLibraryId);
});
test('[XAT-5121] Create a private library', async ({ myLibrariesPage }) => {
test('[C289881] Create a private library', async ({ myLibrariesPage }) => {
await libraryDialog.createLibraryWithNameAndId(randomLibraryName, randomLibraryId, null, privateVisibility);
await expect(libraryBreadcrumb.getItemByTitle(randomLibraryName)).toBeVisible();
@ -149,7 +149,7 @@ test.describe('Create Libraries ', () => {
createdLibrariesIds.push(randomLibraryId);
});
test('[XAT-5122] Create a library with a given ID and description', async ({ myLibrariesPage }) => {
test('[C289882] Create a library with a given ID and description', async ({ myLibrariesPage }) => {
const libraryViewDetails = myLibrariesPage.acaHeader.viewDetails;
const libraryDetails = myLibrariesPage.libraryDetails;
@ -169,7 +169,7 @@ test.describe('Create Libraries ', () => {
createdLibrariesIds.push(randomLibraryId);
});
test('[XAT-5126] Create Library - Cancel button', async () => {
test('[C280029] Cancel button', async () => {
await expect(libraryDialog.getDialogTitle(libraryDialogTitle)).toBeVisible();
await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName);
await libraryDialog.cancelButton.click();
@ -178,7 +178,7 @@ test.describe('Create Libraries ', () => {
await expect(libraryTable.getRowByName(randomLibraryName)).toHaveCount(0);
});
test('[XAT-5127] Create multiple sites with same name but different IDs', async ({ myLibrariesPage }) => {
test('[C280030] Create 2 libraries with same name but different IDs', async ({ myLibrariesPage }) => {
const libraryName = commonLibraryName + ' (' + commonLibraryName + ')';
const libraryName2 = commonLibraryName + ' (' + randomLibraryId + ')';
@ -193,7 +193,7 @@ test.describe('Create Libraries ', () => {
});
});
test('[XAT-5123] Library ID cannot contain special characters', async () => {
test('[C280026] Library ID cannot contain special characters', async () => {
const idsWithSpecialChars = [
'a!a',
'a@a',
@ -226,7 +226,7 @@ test.describe('Create Libraries ', () => {
}
});
test('[XAT-5124] Duplicate library ID', async () => {
test('[C280027] Duplicate library ID', async () => {
await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName);
await libraryDialog.getLabelText(libraryIdLabel).clear();
await libraryDialog.getLabelText(libraryIdLabel).fill(commonLibraryName);
@ -237,7 +237,7 @@ test.describe('Create Libraries ', () => {
expect(await libraryDialog.isErrorMessageDisplayed(libraryErrors.libraryIdIsNotAvailable), errorMessageNotPresent).toBe(true);
});
test('[XAT-5125] Create library using the ID of a library from the Trashcan', async () => {
test('[C280028] Create library using the ID of a library from the Trashcan', async () => {
await libraryDialog.getLabelText(libraryNameLabel).fill(randomLibraryName);
await libraryDialog.getLabelText(libraryIdLabel).clear();
await libraryDialog.getLabelText(libraryIdLabel).fill(commonTrashLibraryName);

View File

@ -1,3 +1,3 @@
{
"XAT-5017": "https://hyland.atlassian.net/browse/ACS-8888"
"C280502": "https://hyland.atlassian.net/browse/ACS-8888"
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -116,7 +116,7 @@ test.describe('Delete and undo delete', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5016] Delete a file and check snackbar notification', async ({ personalFiles, trashPage }) => {
test('[C217125] delete a file and check notification', async ({ personalFiles, trashPage }) => {
let items = await personalFiles.dataTable.getRowsCount();
await personalFiles.dataTable.selectItems(file1);
await personalFiles.acaHeader.clickMoreActions();
@ -133,7 +133,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.dataTable.isItemPresent(file1)).toBeTruthy();
});
test('[XAT-5017] Delete multiple files and check snackbar notification', async ({ personalFiles, trashPage }) => {
test('[C280502] delete multiple files and check notification', async ({ personalFiles, trashPage }) => {
await personalFiles.page.reload({ waitUntil: 'load' });
let items = await personalFiles.dataTable.getRowsCount();
await personalFiles.dataTable.selectItems(file2, file3);
@ -150,7 +150,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.dataTable.isItemPresent(file3)).toBeTruthy();
});
test('[XAT-5018] Delete a folder with content', async ({ personalFiles, trashPage }) => {
test('[C217126] delete a folder with content', async ({ personalFiles, trashPage }) => {
let items = await personalFiles.dataTable.getRowsCount();
await personalFiles.dataTable.selectItems(folder1);
await personalFiles.acaHeader.clickMoreActions();
@ -164,7 +164,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.dataTable.isItemPresent(file1InFolder)).toBeFalsy();
});
test(`[XAT-5019] Delete a folder containing files that can't be deleted (e.g. locked files)`, async ({ personalFiles, trashPage }) => {
test('[C217127] delete a folder containing locked files', async ({ personalFiles, trashPage }) => {
await personalFiles.dataTable.selectItems(folder2);
await personalFiles.acaHeader.clickMoreActions();
await personalFiles.matMenu.clickMenuItem('Delete');
@ -176,7 +176,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.dataTable.isItemPresent(fileLocked1)).toBeFalsy();
});
test('[XAT-5020] Notification on unsuccessful multiple items deletion - some items fail to delete', async ({ personalFiles }) => {
test('[C217129] notification on multiple items deletion - some items fail to delete', async ({ personalFiles }) => {
await personalFiles.dataTable.selectItems(file4, folder3);
await personalFiles.acaHeader.clickMoreActions();
await personalFiles.matMenu.clickMenuItem('Delete');
@ -185,7 +185,7 @@ test.describe('Delete and undo delete', () => {
expect(action).toContain('Undo');
});
test('[XAT-5021] Notification on unsuccessful multiple items deletion - all items fail to delete', async ({ personalFiles }) => {
test('[C217130] notification on multiple items deletion - all items fail to delete', async ({ personalFiles }) => {
await personalFiles.dataTable.selectItems(folder4, folder5);
await personalFiles.acaHeader.clickMoreActions();
await personalFiles.matMenu.clickMenuItem('Delete');
@ -193,7 +193,7 @@ test.describe('Delete and undo delete', () => {
await expect(personalFiles.snackBar.actionButton).toBeHidden();
});
test('[XAT-5022] Undo delete of a single file restores the file', async ({ personalFiles }) => {
test('[C217132] undo delete of file', async ({ personalFiles }) => {
const items = await personalFiles.dataTable.getRowsCount();
await personalFiles.dataTable.selectItems(file5);
@ -206,7 +206,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.pagination.getRange()).toContain(`1-${items} of ${items}`);
});
test('[XAT-5024] Undo restores the deleted folder and its content', async ({ personalFiles }) => {
test('[C280503] undo delete of folder with content', async ({ personalFiles }) => {
await personalFiles.dataTable.selectItems(folder6);
await personalFiles.acaHeader.clickMoreActions();
await personalFiles.matMenu.clickMenuItem('Delete');
@ -218,7 +218,7 @@ test.describe('Delete and undo delete', () => {
expect(await personalFiles.dataTable.isItemPresent(file2InFolder)).toBeTruthy();
});
test('[XAT-5023] Undo delete of multiple files restores all of the files', async ({ personalFiles }) => {
test('[C280504] undo delete of multiple files', async ({ personalFiles }) => {
await personalFiles.dataTable.selectItems(file6, file7);
await personalFiles.acaHeader.clickMoreActions();
await personalFiles.matMenu.clickMenuItem('Delete');

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -79,7 +79,7 @@ test.describe('Delete and undo delete', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5103] Permanently Delete a file', async ({ trashPage }) => {
test('[C217091] delete a file', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file1);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.deleteButton.click();
@ -88,7 +88,7 @@ test.describe('Delete and undo delete', () => {
expect(await trashPage.dataTable.isItemPresent(file1)).toBeFalsy();
});
test('[XAT-5104] Permanently delete a folder', async ({ trashPage }) => {
test('[C280416] delete a folder', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(folder1);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.deleteButton.click();
@ -97,7 +97,7 @@ test.describe('Delete and undo delete', () => {
expect(await trashPage.dataTable.isItemPresent(folder1)).toBeFalsy();
});
test('[XAT-5108] Permanently delete a library', async ({ trashPage }) => {
test('[C290103] delete a library', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(site);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.deleteButton.click();
@ -106,7 +106,7 @@ test.describe('Delete and undo delete', () => {
expect(await trashPage.dataTable.isItemPresent(site)).toBeFalsy();
});
test('[XAT-5105] Permanently delete multiple items', async ({ trashPage }) => {
test('[C280417] delete multiple items', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file2, folder2);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.deleteButton.click();
@ -116,7 +116,7 @@ test.describe('Delete and undo delete', () => {
expect(await trashPage.dataTable.isItemPresent(folder2)).toBeFalsy();
});
test('[XAT-5106] Permanently delete - Confirmation dialog UI', async ({ trashPage }) => {
test('[C269113] Confirmation dialog UI', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file3);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.waitForDialog();
@ -128,7 +128,7 @@ test.describe('Delete and undo delete', () => {
expect(await trashPage.deleteDialog.isKeepEnabled()).toBeTruthy();
});
test('[XAT-5107] ""Keep"" action cancels the deletion', async ({ trashPage }) => {
test('[C269115] Keep action cancels the deletion', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file3);
await trashPage.acaHeader.permanentlyDeleteButton.click();
await trashPage.deleteDialog.waitForDialog();

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -91,25 +91,25 @@ test.describe('Restore from Trash', () => {
expect(await trashPage.dataTable.isItemPresent(nodeName)).toBeFalsy();
}
test('[XAT-5109] Restore file', async ({ trashPage, personalFiles }) => {
test('[C217177] restore file', async ({ trashPage, personalFiles }) => {
await restoreNode(trashPage, file1);
await personalFiles.navigate();
expect(await personalFiles.dataTable.isItemPresent(file1)).toBeTruthy();
});
test('[XAT-5110] Restore folder', async ({ trashPage, personalFiles }) => {
test('[C280438] restore folder', async ({ trashPage, personalFiles }) => {
await restoreNode(trashPage, folder1);
await personalFiles.navigate();
expect(await personalFiles.dataTable.isItemPresent(folder1)).toBeTruthy();
});
test('[XAT-5117] Restore library', async ({ trashPage, myLibrariesPage }) => {
test('[C290104] restore library', async ({ trashPage, myLibrariesPage }) => {
await restoreNode(trashPage, site1);
await myLibrariesPage.navigate();
expect(await myLibrariesPage.dataTable.isItemPresent(site1)).toBeTruthy();
});
test('[XAT-5111] Restore multiple items', async ({ trashPage, personalFiles }) => {
test('[C217182] restore multiple items', async ({ trashPage, personalFiles }) => {
await trashPage.dataTable.selectItems(file2, folder2);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.verifySnackBarActionText(`Restore successful`);
@ -122,7 +122,7 @@ test.describe('Restore from Trash', () => {
expect(await personalFiles.dataTable.isItemPresent(folder2)).toBeTruthy();
});
test('[XAT-5112] Restore file - View from notification', async ({ trashPage, personalFiles }) => {
test('[C217181] View from notification', async ({ trashPage, personalFiles }) => {
await trashPage.dataTable.selectItems(file3);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.clickSnackBarAction();
@ -162,13 +162,13 @@ test.describe('Restore from Trash', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5113] Restore an item when another one with same name already exists on the restore location', async ({ trashPage }) => {
test('[C217178] Restore a file when another file with same name exists on the restore location', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file1);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.verifySnackBarActionText(`Can't restore, ${file1} already exists`);
});
test('[XAT-5114] Restore a file when original location no longer exists', async ({ trashPage }) => {
test('[C217179] Restore a file when original location no longer exists', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file2);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.verifySnackBarActionText(`Can't restore ${file2}, the original location no longer exists`);
@ -222,13 +222,13 @@ test.describe('Restore from Trash', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5115] Notification on partial success - one failure', async ({ trashPage }) => {
test('[C217183] one failure', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file1, file2);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.verifySnackBarActionText(`Can't restore ${file1}, the original location no longer exists`);
});
test('[XAT-5116] Notification on partial success - multiple failures', async ({ trashPage }) => {
test('[C217184] multiple failures', async ({ trashPage }) => {
await trashPage.dataTable.selectItems(file3, file4, file5);
await trashPage.acaHeader.restoreButton.click();
await trashPage.snackBar.verifySnackBarActionText('2 items not restored because of issues with the restore location');

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -73,10 +73,8 @@ test.describe('Edit offline - on Personal Files', () => {
test('[XAT-5304] File is locked and downloaded when clicking Edit offline', async ({ personalFiles }) => {
await personalFiles.dataTable.selectItems(file1);
await personalFiles.acaHeader.clickMoreActions();
const [download] = await Promise.all([
personalFiles.page.waitForEvent('download', { timeout: 5000 }),
personalFiles.matMenu.clickMenuItem('Edit Offline')
]);
await personalFiles.matMenu.clickMenuItem('Edit Offline');
const [download] = await Promise.all([personalFiles.page.waitForEvent('download')]);
expect(download.suggestedFilename()).toBe(file1);
});

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,26 +0,0 @@
{
"extends": "../../../.eslintrc.json",
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"e2e/playwright/folder-information-actions/tsconfig.e2e.json"
],
"createDefaultProgram": true
},
"plugins": [
"rxjs",
"unicorn"
],
"rules": {
"@typescript-eslint/no-floating-promises": "off"
}
}
]
}

View File

@ -1,42 +0,0 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { PlaywrightTestConfig } from '@playwright/test';
import { CustomConfig, getGlobalConfig, getExcludedTestsRegExpArray } from '@alfresco/aca-playwright-shared';
import EXCLUDED_JSON from './exclude.tests.json';
const config: PlaywrightTestConfig<CustomConfig> = {
...getGlobalConfig,
grepInvert: getExcludedTestsRegExpArray(EXCLUDED_JSON, 'Folder Information Actions'),
projects: [
{
name: 'Folder Information Actions',
testDir: './src/tests',
use: {}
}
]
};
export default config;

View File

@ -1,31 +0,0 @@
{
"name": "folder-information-actions-e2e",
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/playwright/folder-information-actions",
"projectType": "application",
"targets": {
"e2e": {
"executor": "nx:run-commands",
"options": {
"commands": ["npx playwright test --config=e2e/playwright/folder-information-actions/playwright.config.ts"]
},
"configurations": {
"production": {
"devServerTarget": "content-ce:serve:production"
},
"ui": {
"args": ["--ui"]
},
"debug": {
"args": ["--debug"]
},
"headed": {
"args": ["--headed"]
}
}
},
"lint": {
"executor": "@angular-eslint/builder:lint"
}
}
}

View File

@ -1,195 +0,0 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { expect } from '@playwright/test';
import {
ApiClientFactory,
NodesApi,
Utils,
test,
TrashcanApi,
TEST_FILES,
FileActionsApi,
PersonalFilesPage,
MyLibrariesPage,
SitesApi,
SearchPage
} from '@alfresco/aca-playwright-shared';
test.describe('Actions - Folder Information', () => {
const username = `user-e2e-${Utils.random()}`;
const emptyFolder = `folder17722-${Utils.random()}`;
const folder1File = `folder17715-${Utils.random()}`;
const folderXFiles = `folder17752-${Utils.random()}`;
const folderXFilesAndFolders = `folder17753-1-${Utils.random()}`;
const folderInsideFolder = `folder17753-2-${Utils.random()}`;
const folderInLibrary = `folder17758-${Utils.random()}`;
const libraryForFolder = `library17758-${Utils.random()}`;
const folderForSearch = `folder17759-${Utils.random()}`;
const folderNested1 = `folder17766-1-${Utils.random()}`;
const folderNested2 = `folder17766-1-${Utils.random()}`;
const folderNested3 = `folder17766-1-${Utils.random()}`;
const file1 = `file1-${Utils.random()}.docx`;
const file2 = `file2-${Utils.random()}.docx`;
const file3 = `file3-${Utils.random()}.docx`;
const file4 = `file4-${Utils.random()}.docx`;
const file5 = `file5-${Utils.random()}.docx`;
const file6 = `file6-${Utils.random()}.docx`;
const file7 = `file7-${Utils.random()}.docx`;
const file8 = `file8-${Utils.random()}.docx`;
const file9 = `file9-${Utils.random()}.docx`;
const file10 = `file10-${Utils.random()}.docx`;
const file11 = `file10-${Utils.random()}.docx`;
const file12 = `file10-${Utils.random()}.docx`;
const file13 = `file10-${Utils.random()}.docx`;
let nodesApi: NodesApi;
let trashcanApi: TrashcanApi;
let fileActionsApi: FileActionsApi;
let sitesApi: SitesApi;
let folder1FileId: string;
let folderXFilesId: string;
let folderXFilesAndFoldersId: string;
let folderInsideFolderId: string;
let folderInLibraryId: string;
let siteId: string;
let folderForSearchId: string;
let folderNested1Id: string;
let folderNested2Id: string;
let folderNested3Id: string;
test.beforeAll(async () => {
const apiService = new ApiClientFactory();
await apiService.setUpAcaBackend('admin');
await apiService.createUser({ username: username });
nodesApi = await NodesApi.initialize(username, username);
trashcanApi = await TrashcanApi.initialize(username, username);
fileActionsApi = await FileActionsApi.initialize(username, username);
sitesApi = await SitesApi.initialize(username, username);
siteId = (await sitesApi.createSite(libraryForFolder)).entry.id;
const docLibId = await sitesApi.getDocLibId(siteId);
await nodesApi.createFolder(emptyFolder, '-my-');
folder1FileId = (await nodesApi.createFolder(folder1File, '-my-')).entry.id;
folderXFilesId = (await nodesApi.createFolder(folderXFiles, '-my-')).entry.id;
folderXFilesAndFoldersId = (await nodesApi.createFolder(folderXFilesAndFolders, '-my-')).entry.id;
folderInsideFolderId = (await nodesApi.createFolder(folderInsideFolder, folderXFilesAndFoldersId)).entry.id;
folderInLibraryId = (await nodesApi.createFolder(folderInLibrary, docLibId)).entry.id;
folderForSearchId = (await nodesApi.createFolder(folderForSearch, '-my-')).entry.id;
folderNested1Id = (await nodesApi.createFolder(folderNested1, '-my-')).entry.id;
folderNested2Id = (await nodesApi.createFolder(folderNested2, folderNested1Id)).entry.id;
folderNested3Id = (await nodesApi.createFolder(folderNested3, folderNested2Id)).entry.id;
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file1, folder1FileId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file2, folderXFilesId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file3, folderXFilesId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file4, folderXFilesId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file5, folderXFilesAndFoldersId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file6, folderXFilesAndFoldersId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file7, folderXFilesAndFoldersId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file8, folderInsideFolderId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file9, folderInsideFolderId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file10, folderInLibraryId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file11, folderForSearchId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file12, folderForSearchId);
await fileActionsApi.uploadFileWithRename(TEST_FILES.DOCX.path, file13, folderNested3Id);
});
test.beforeEach(async ({ loginPage }) => {
await Utils.tryLoginUser(loginPage, username, username, 'Main beforeEach failed');
});
test.afterAll(async () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
async function checkFolderInformation(
page: PersonalFilesPage | MyLibrariesPage | SearchPage,
folderName: string,
expectedSize: string,
location: string,
isEmptyFolder?: 'isEmpty'
) {
await page.dataTable.selectItems(folderName);
await page.acaHeader.clickMoreActions();
await page.matMenu.clickMenuItem('Folder Information');
await expect(async () => {
expect(await page.folderInformationDialog.folderSize.textContent()).toContain(expectedSize);
}).toPass({
intervals: [1_000],
timeout: 5_000
});
if (!isEmptyFolder) {
expect(await page.folderInformationDialog.getFolderSizeNumber()).toBeGreaterThan(0);
}
expect(await page.folderInformationDialog.folderLocation.textContent()).toContain(location);
expect(await page.folderInformationDialog.folderCreationDate.textContent()).toContain('ago');
expect(await page.folderInformationDialog.folderModifiedDate.textContent()).toContain('ago');
await page.folderInformationDialog.doneButton.click();
await page.folderInformationDialog.folderName.waitFor({ state: 'hidden' });
}
test('[XAT-17722] Folder information Empty folder size and number of documents as 0', async ({ personalFiles }) => {
await personalFiles.navigate();
await checkFolderInformation(personalFiles, emptyFolder, '0 bytes for 0 files', `/Company Home/User Homes/${username}`, 'isEmpty');
});
test('[XAT-17715] Folder information correct folder size and number of documents - single file', async ({ personalFiles }) => {
await personalFiles.navigate();
await checkFolderInformation(personalFiles, folder1File, 'for 1 files', `/Company Home/User Homes/${username}`);
});
test('[XAT-17752] Folder information correct folder size and number of documents - multiple files', async ({ personalFiles }) => {
await personalFiles.navigate();
await checkFolderInformation(personalFiles, folderXFiles, 'for 3 files', `/Company Home/User Homes/${username}`);
});
test('[XAT-17753] Folder information correct folder size and number of documents - folder and files', async ({ personalFiles }) => {
await personalFiles.navigate();
await checkFolderInformation(personalFiles, folderXFilesAndFolders, 'for 5 files', `/Company Home/User Homes/${username}`);
});
test('[XAT-17758] Folder information correct folder size and number of documents - from libraries', async ({ myLibrariesPage }) => {
await myLibrariesPage.navigate();
await myLibrariesPage.dataTable.getRowByName(libraryForFolder).dblclick();
await checkFolderInformation(myLibrariesPage, folderInLibrary, 'for 1 files', `/Company Home/Sites/${libraryForFolder}/documentLibrary`);
});
test('[XAT-17759] Folder information correct folder size and number of documents - from search', async ({ personalFiles, searchPage }) => {
await personalFiles.navigate();
await searchPage.searchWithin(folderForSearch, 'folders');
await checkFolderInformation(searchPage, folderForSearch, 'for 2 files', `/Company Home/User Homes/${username}`);
});
test('[XAT-17766] Folder information correct folder size and number of documents - nested folders', async ({ personalFiles }) => {
await personalFiles.navigate();
await personalFiles.dataTable.getRowByName(folderNested1).dblclick();
await personalFiles.dataTable.getRowByName(folderNested2).dblclick();
await checkFolderInformation(
personalFiles,
folderNested3,
'for 1 files',
`/Company Home/User Homes/${username}/${folderNested1}/${folderNested2}`
);
});
});

View File

@ -1,15 +0,0 @@
{
"extends": "../../../tsconfig.adf.json",
"compilerOptions": {
"outDir": "../../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es2017",
"types": ["jasmine", "jasminewd2", "node"],
"skipLibCheck": true,
"paths": {
"@alfresco/aca-playwright-shared": ["dist/@alfresco/aca-playwright-shared"]
}
},
"exclude": ["node_modules"]
}

View File

@ -1,15 +0,0 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es2017",
"types": ["jasmine", "jasminewd2", "node", "@playwright/test"],
"skipLibCheck": true,
"paths": {
"@alfresco/aca-playwright-shared": ["dist/@alfresco/aca-playwright-shared"]
}
},
"exclude": ["node_modules"]
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -131,23 +131,24 @@ test.describe('Folder Rules Actions', () => {
test('[XAT-888] Create a rule with multiple actions', async ({ personalFiles, nodesPage }) => {
const checkInValue = 'check In Value';
const actionValue = 'Site Container [st:siteContainer]';
const specialiseTypeValue = 'Action Base Type [act:actionbase]';
const actionValue = ' A site which contains sfdc content [sfdc:site] ';
const autoDeclareOptionsValue = 'For all major and minor versions [ALL]';
const simpleWorkFlow = 'accept reject';
await personalFiles.navigate({ remoteUrl: `#/nodes/${randomFolderName1Id}/rules` });
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 0);
await nodesPage.actionsDropdown.selectAction(ActionType.CheckIn, 1);
await nodesPage.actionsDropdown.insertCheckInActionValues(checkInValue, 1);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 2);
await nodesPage.actionsDropdown.insertAddAspectActionValues(actionValue, 2);
await nodesPage.actionsDropdown.selectAction(ActionType.SpecialiseType, 3);
await nodesPage.actionsDropdown.insertSpecialiseTypeActionValues(specialiseTypeValue, 3);
await nodesPage.actionsDropdown.selectAction(ActionType.SimpleWorkflow, 4);
await nodesPage.actionsDropdown.insertSimpleWorkflowActionValues(simpleWorkFlow, 4);
await nodesPage.actionsDropdown.selectAction(ActionType.HideRecord, 0);
await nodesPage.actionsDropdown.selectAction(ActionType.IncrementCounter, 1);
await nodesPage.actionsDropdown.selectAction(ActionType.CheckIn, 2);
await nodesPage.actionsDropdown.insertCheckInActionValues(checkInValue, 2);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 3);
await nodesPage.actionsDropdown.insertAddAspectActionValues(actionValue, 3);
await nodesPage.actionsDropdown.selectAction(ActionType.AutoDeclareOptions, 4);
await nodesPage.actionsDropdown.insertAutoDeclareOptionsActionValues(autoDeclareOptionsValue, 4);
await nodesPage.actionsDropdown.selectAction(ActionType.SimpleWorkflow, 5);
await nodesPage.actionsDropdown.insertSimpleWorkflowActionValues(simpleWorkFlow, 5);
await nodesPage.manageRulesDialog.createRuleButton.click();
@ -184,18 +185,18 @@ test.describe('Folder Rules Actions', () => {
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Controls', 0);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 1);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Countable', 1);
await nodesPage.actionsDropdown.insertAddAspectActionValues('CMM', 1);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 2);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Incomplete', 2);
await nodesPage.actionsDropdown.insertAddAspectActionValues('folder', 2);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 3);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Site container', 3);
await nodesPage.actionsDropdown.insertAddAspectActionValues('site which', 3);
await nodesPage.manageRulesDialog.createRuleButton.click();
await nodesPage.manageRulesDialog.createRuleButton.waitFor({ state: 'hidden' });
await nodesPage.manageRules.getGroupsList(randomRuleName).click();
await nodesPage.manageRules.checkAspects(['cm:generalclassifiable', 'cm:countable', 'sys:incomplete', 'st:siteContainer']);
await nodesPage.manageRules.checkAspects(['sc:controlsAreClearance', 'sfdc:objectModel', 'sfdc:folder', 'sfdc:site']);
});
test('[XAT-891] Prevent rule creation after clicking on cancel during selecting destination folder', async ({ nodesPage, personalFiles }) => {
@ -203,7 +204,7 @@ test.describe('Folder Rules Actions', () => {
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Controls', 0);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 1);
await nodesPage.manageRulesDialog.destinationFolderButton.click();
@ -216,7 +217,7 @@ test.describe('Folder Rules Actions', () => {
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Controls', 0);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
await nodesPage.actionsDropdown.selectAction(ActionType.Copy, 1);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
@ -227,7 +228,7 @@ test.describe('Folder Rules Actions', () => {
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Controls', 0);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
await nodesPage.actionsDropdown.insertAddAspectActionValues('None', 0);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeDisabled();
@ -238,7 +239,7 @@ test.describe('Folder Rules Actions', () => {
await nodesPage.toolbar.clickCreateRuleButton();
await nodesPage.manageRulesDialog.ruleNameInputLocator.fill(randomRuleName);
await nodesPage.actionsDropdown.selectAction(ActionType.AddAspect, 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Classifiable', 0);
await nodesPage.actionsDropdown.insertAddAspectActionValues('Controls', 0);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();
await nodesPage.actionsDropdown.selectAction(ActionType.CheckIn, 1);
await expect(nodesPage.manageRulesDialog.createRuleButton).toBeEnabled();

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -55,7 +55,7 @@ test.describe('Info Drawer - Comments', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5524] from Personal Files - Comments tab default fields', async ({ personalFiles }) => {
test('[C299173] from Personal Files - Comments tab default fields', async ({ personalFiles }) => {
const personalFolderName = `personalFolder-e2e-${Utils.random()}`;
await nodesApi.createFolder(personalFolderName);
await fileActionsApi.waitForNodes(personalFolderName, { expect: 1 });
@ -70,7 +70,7 @@ test.describe('Info Drawer - Comments', () => {
await expect(personalFiles.infoDrawer.addCommentButton).toBeDisabled();
});
test('[XAT-5544] from Favorites - Add a comment on a folder', async ({ favoritePage }) => {
test('[C299209] from Favorites - Add a comment on a folder', async ({ favoritePage }) => {
const favoriteFolderName = `favoriteFolder-e2e-${Utils.random()}`;
const folderFavId = (await nodesApi.createFolder(favoriteFolderName)).entry.id;
await favoritesActions.addFavoritesByIds('folder', [folderFavId]);
@ -83,10 +83,11 @@ test.describe('Info Drawer - Comments', () => {
await expect(favoritePage.infoDrawer.commentInputField).toBeVisible();
await favoritePage.infoDrawer.addCommentToNode(commentText);
await expect(favoritePage.infoDrawer.addCommentButton).toBeDisabled();
expect(await favoritePage.infoDrawer.getCommentsCountFromList()).toEqual(1);
expect(await favoritePage.infoDrawer.checkCommentsHeaderCount()).toEqual(1);
expect(await favoritePage.infoDrawer.verifyCommentsCountFromList(1));
});
test('[XAT-5533] from Shared Files - Comments are displayed ordered by created date in descending order', async ({ sharedPage }) => {
test('[C299189] from Shared Files - Comments are displayed ordered by created date in descending order', async ({ sharedPage }) => {
await sharedPage.navigate();
const sharedFileName = `sharedFile-e2e-${Utils.random()}`;
const e2eCommentFirst = `e2e-comment-${Utils.random()}`;
@ -107,7 +108,7 @@ test.describe('Info Drawer - Comments', () => {
await expect(sharedPage.infoDrawer.commentTextContent.nth(1)).toHaveText(e2eCommentFirst);
});
test('[XAT-5539] from Recent Files - Add a comment on a file', async ({ recentFilesPage }) => {
test('[C299195] from Recent Files - Add a comment on a file', async ({ recentFilesPage }) => {
const recentFile = `e2e-recentFile-${Utils.random()}`;
await nodesApi.createFile(recentFile);
await fileActionsApi.waitForNodes(recentFile, { expect: 1 });
@ -119,10 +120,11 @@ test.describe('Info Drawer - Comments', () => {
await expect(recentFilesPage.infoDrawer.commentInputField).toBeVisible();
await recentFilesPage.infoDrawer.addCommentToNode(commentText);
await expect(recentFilesPage.infoDrawer.addCommentButton).toBeDisabled();
expect(await recentFilesPage.infoDrawer.getCommentsCountFromList()).toEqual(1);
expect(await recentFilesPage.infoDrawer.checkCommentsHeaderCount()).toEqual(1);
expect(await recentFilesPage.infoDrawer.verifyCommentsCountFromList(1));
});
test('[XAT-5540] Comment info display - File from Favorites', async ({ favoritePage }) => {
test('[C299196] Comment info display - File from Favorites', async ({ favoritePage }) => {
const e2eCommentFirst = `e2e-comment-${Utils.random()}`;
const commentInfoFileName = `e2e-commentFile-${Utils.random()}`;
const commentInfoFileId = (await nodesApi.createFile(commentInfoFileName)).entry.id;

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -132,7 +132,7 @@ test.describe('Info Drawer - File Folder Properties', () => {
await personalFiles.acaHeader.viewDetails.click();
}
test('[XAT-5512] View properties - Default tabs', async ({ personalFiles }) => {
test('[C299162] View properties - Default tabs', async ({ personalFiles }) => {
await navigateAndOpenInfoDrawer(personalFiles, FolderC299162);
expect(await personalFiles.infoDrawer.getHeaderTitle()).toEqual(FolderC299162);
await expect(personalFiles.infoDrawer.propertiesTab).toBeVisible();
@ -140,7 +140,7 @@ test.describe('Info Drawer - File Folder Properties', () => {
expect(await personalFiles.infoDrawer.getTabsCount()).toEqual(2);
});
test('[XAT-5514] View properties - Should be able to make the folders info drawer expandable as for Sites', async ({ personalFiles }) => {
test('[C599174] View properties - Should be able to make the files/folders info drawer expandable as for Sites', async ({ personalFiles }) => {
await navigateAndOpenInfoDrawer(personalFiles, FolderC599174);
await personalFiles.infoDrawer.expandDetailsButton.click();
await expect(personalFiles.infoDrawer.expandedDetailsPermissionsTab).toBeVisible();
@ -179,12 +179,6 @@ test.describe('Info Drawer - File Folder Properties', () => {
test('[XAT-17240] Remove a tag from a node', async ({ personalFiles }) => {
await fileActionsApi.waitForNodes(Folder17240, { expect: 1 });
await tagsApi.assignTagToNode(Folder17240Id, tagBody);
await expect(async () => {
expect((await tagsApi.listTagsForNode(Folder17240Id)).list.entries.length).toEqual(1);
}).toPass({
intervals: [1_000],
timeout: 10_000
});
await personalFiles.navigate();
await Utils.reloadPageIfRowNotVisible(personalFiles, Folder17240);
await expect(personalFiles.dataTable.getRowByName(Folder17240)).toBeVisible();

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -22,13 +22,12 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { expect } from '@playwright/test';
import { expect, Page } from '@playwright/test';
import { ApiClientFactory, test, TrashcanApi, NodesApi, FileActionsApi, TEST_FILES, Utils } from '@alfresco/aca-playwright-shared';
test.describe('File preview', () => {
const timestamp = new Date().getTime();
const username = `user1-${timestamp}`;
const fileName = `file1-${timestamp}.pdf`;
let nodesApi: NodesApi;
let trashcanApi: TrashcanApi;
let fileActionsApi: FileActionsApi;
@ -41,8 +40,6 @@ test.describe('File preview', () => {
nodesApi = await NodesApi.initialize(username, username);
trashcanApi = await TrashcanApi.initialize(username, username);
fileActionsApi = await FileActionsApi.initialize(username, username);
await fileActionsApi.uploadFileWithRename(TEST_FILES.PDF.path, fileName, '-my-');
await fileActionsApi.waitForNodes(fileName, { expect: 1 });
} catch (error) {
console.error(`beforeAll failed : ${error}`);
}
@ -56,12 +53,26 @@ test.describe('File preview', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-17780] Can open viewer while the info drawer is opened', async ({ personalFiles }) => {
async function checkFileContent(page: Page, pageNumber: number, text: string): Promise<void> {
const allPages = page.locator('.canvasWrapper > canvas').first();
const pageLoaded = page.locator(`div[data-page-number="${pageNumber}"][data-loaded="true"]`);
const textLayerLoaded = page.locator(`div[data-page-number="${pageNumber}"] .textLayer`);
const specificText = textLayerLoaded.textContent();
await expect(allPages).toBeVisible();
await expect(pageLoaded).toBeVisible();
await expect(textLayerLoaded).toBeVisible();
expect(await specificText).toContain(text);
}
test('[C595967] Should preview document from the info drawer', async ({ personalFiles }) => {
const fileName = `file1-${timestamp}.pdf`;
await fileActionsApi.uploadFileWithRename(TEST_FILES.PDF.path, fileName, '-my-');
await fileActionsApi.waitForNodes(fileName, { expect: 1 });
await personalFiles.navigate();
await Utils.reloadPageIfRowNotVisible(personalFiles, fileName);
await personalFiles.dataTable.getRowByName(fileName).click();
await personalFiles.acaHeader.viewButton.click();
await expect(personalFiles.viewer.pdfViewerContentPages.first()).toBeVisible();
expect(await personalFiles.viewer.viewerDocument.textContent()).toContain('PDF');
await checkFileContent(personalFiles.page, 1, 'This is a small demonstration');
});
});

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -53,7 +53,7 @@ test.describe('Info Drawer - General', () => {
await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed');
});
test('[XAT-5511] Info drawer closes on page refresh', async ({ personalFiles }) => {
test('[C268999] Info drawer closes on page refresh', async ({ personalFiles }) => {
const parentFolder = `parent-general-${Utils.random()}`;
const file1 = `file1-${Utils.random()}.txt`;
const folder1 = `folder1-${Utils.random()}`;

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -25,35 +25,22 @@
import { expect } from '@playwright/test';
import { ApiClientFactory, Utils, test, SitesApi, QueriesApi, SITE_VISIBILITY, SITE_ROLES } from '@alfresco/aca-playwright-shared';
async function expectSiteToBeDefined(siteName: string, queriesApi: QueriesApi) {
await expect(async () => {
expect(await queriesApi.waitForSites(siteName, { expect: 1 })).toEqual(1);
}).toPass({
intervals: [1_000],
timeout: 10_000
});
}
test.describe('Library properties', () => {
let sitesApi: SitesApi;
let queriesApi: QueriesApi;
const username = `user1-${Utils.random()}`;
const site = {
name: `site1-${Utils.random()}`,
id: `site-id-${Utils.random()}`,
visibility: SITE_VISIBILITY.MODERATED,
description: 'my site description'
};
const siteForUpdate = {
name: `site2-${Utils.random()}`,
id: `site-id-${Utils.random()}`,
visibility: SITE_VISIBILITY.MODERATED,
description: 'my initial description'
};
const siteDup = `site3-${Utils.random()}`;
test.beforeAll(async () => {
@ -63,7 +50,6 @@ test.describe('Library properties', () => {
await apiClientFactory.createUser({ username });
sitesApi = await SitesApi.initialize(username, username);
queriesApi = await QueriesApi.initialize(username, username);
await sitesApi.createSite(site.name, site.visibility, site.description, site.id);
await sitesApi.createSite(siteForUpdate.name, siteForUpdate.visibility, siteForUpdate.description, siteForUpdate.id);
await sitesApi.createSite(siteDup);
@ -81,8 +67,7 @@ test.describe('Library properties', () => {
await Utils.deleteNodesSitesEmptyTrashcan(undefined, undefined, 'afterAll failed', sitesApi, [site.id, siteForUpdate.id, siteDup]);
});
test('[XAT-5545] Info drawer opens for a library', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(site.name, queriesApi);
test('[C289336] Info drawer opens for a library', async ({ myLibrariesPage }) => {
await expect(myLibrariesPage.dataTable.getRowByName(site.name)).toBeVisible();
await myLibrariesPage.dataTable.getRowByName(site.name).click();
await myLibrariesPage.acaHeader.viewDetails.click();
@ -102,8 +87,7 @@ test.describe('Library properties', () => {
await expect(myLibrariesPage.libraryDetails.editButton).toBeVisible();
});
test('[XAT-5547] Editable properties', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(site.name, queriesApi);
test('[C289338] Editable properties', async ({ myLibrariesPage }) => {
await myLibrariesPage.dataTable.getRowByName(site.name).click();
await myLibrariesPage.acaHeader.viewDetails.click();
await expect(myLibrariesPage.libraryDetails.infoDrawerPanel).toBeVisible();
@ -120,13 +104,12 @@ test.describe('Library properties', () => {
await expect(myLibrariesPage.libraryDetails.updateButton).toBeDisabled();
});
test('[XAT-5548] Edit site details', async ({ myLibrariesPage }) => {
test('[C289339] Edit site details', async ({ myLibrariesPage }) => {
const siteUpdated = {
name: `site-for-rename-${Utils.random()}`,
visibility: SITE_VISIBILITY.PRIVATE,
description: 'new description'
};
await expectSiteToBeDefined(siteForUpdate.name, queriesApi);
await myLibrariesPage.dataTable.getRowByName(siteForUpdate.name).click();
await myLibrariesPage.acaHeader.viewDetails.click();
@ -149,8 +132,7 @@ test.describe('Library properties', () => {
expect((await sitesApi.getSite(siteForUpdate.id)).entry.visibility).toEqual(siteUpdated.visibility);
});
test('[XAT-5549] Cancel editing a site', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(site.name, queriesApi);
test('[C289340] Cancel editing a site', async ({ myLibrariesPage }) => {
const newName = `new-name-${Utils.random}`;
const newDesc = `new desc ${Utils.random}`;
@ -172,9 +154,10 @@ test.describe('Library properties', () => {
await expect(myLibrariesPage.libraryDetails.infoDrawerPanel).toBeVisible();
});
test('[XAT-5550] Warning appears when editing the name of the library by entering an existing name', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(siteDup, queriesApi);
test('[C289341] Warning appears when editing the name of the library by entering an existing name', async ({ myLibrariesPage }) => {
const queriesApi = await QueriesApi.initialize(username, username);
await queriesApi.waitForSites(site.name, { expect: 1 });
await myLibrariesPage.dataTable.getRowByName(siteDup).click();
await myLibrariesPage.acaHeader.viewDetails.click();
await expect(myLibrariesPage.libraryDetails.infoDrawerPanel).toBeVisible();
@ -186,9 +169,7 @@ test.describe('Library properties', () => {
await expect(myLibrariesPage.libraryDetails.hintMessage).toHaveText('Library name already in use');
});
test('[XAT-5551] Site name too long', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(site.name, queriesApi);
test('[C289342] Site name too long', async ({ myLibrariesPage }) => {
await myLibrariesPage.dataTable.getRowByName(site.name).click();
await myLibrariesPage.acaHeader.viewDetails.click();
await expect(myLibrariesPage.libraryDetails.infoDrawerPanel).toBeVisible();
@ -200,9 +181,7 @@ test.describe('Library properties', () => {
await expect(myLibrariesPage.libraryDetails.updateButton).toBeDisabled();
});
test('[XAT-5552] Site description too long', async ({ myLibrariesPage }) => {
await expectSiteToBeDefined(site.name, queriesApi);
test('[C289343] Site description too long', async ({ myLibrariesPage }) => {
await Utils.reloadPageIfRowNotVisible(myLibrariesPage, site.name);
await myLibrariesPage.dataTable.getRowByName(site.name).click();
await myLibrariesPage.acaHeader.viewDetails.click();
@ -250,7 +229,7 @@ test.describe('Non manager', () => {
await Utils.deleteNodesSitesEmptyTrashcan(undefined, undefined, 'afterAll failed', sitesApi, [site.id]);
});
test('[XAT-5546] View Details button is not displayed when user is not the library manager', async ({ loginPage, myLibrariesPage }) => {
test('[C289337] Info drawer button is not displayed when user is not the library manager', async ({ loginPage, myLibrariesPage }) => {
await loginPage.loginUser({ username: user2, password: user2 }, { withNavigation: true, waitForLoading: true });
await myLibrariesPage.navigate();
@ -258,7 +237,7 @@ test.describe('Non manager', () => {
await expect(myLibrariesPage.acaHeader.viewDetails).toBeHidden();
});
test('[XAT-5553] Error notification when editing with no rights', async ({ loginPage, myLibrariesPage }) => {
test('[C289344] Error notification when editing with no rights', async ({ loginPage, myLibrariesPage }) => {
await loginPage.loginUser({ username: user3, password: user3 }, { withNavigation: true, waitForLoading: true });
await myLibrariesPage.navigate();

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -175,7 +175,7 @@ test.describe('Library actions ', () => {
}
});
test('[XAT-5132] Leave a library - from My Libraries', async () => {
test('[C290106] Leave a library from My Libraries', async () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library1, managerRole)).toBeVisible();
await libraryTable.performActionFromExpandableMenu(user1Library1, leaveLibraryButton);
await expect.soft(confirmDialog.getDialogTitle('Leave this library?')).toBeVisible();
@ -187,14 +187,14 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getRowByName(user1Library1)).toBeHidden();
});
test('[XAT-5136] Cancel Leave Library', async () => {
test('[C290111] Cancel Leave Library', async () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library5, managerRole)).toBeVisible();
await libraryTable.performActionFromExpandableMenu(user1Library5, leaveLibraryButton);
await confirmDialog.cancelButton.click();
await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library5, managerRole)).toBeVisible();
});
test('[XAT-5137] Leave a library - failure notification', async () => {
test('[C290107] Leave a library - failure notification', async () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user2Library1, managerRole)).toBeVisible();
await libraryTable.performActionFromExpandableMenu(user2Library1, leaveLibraryButton);
await confirmDialog.okButton.click();
@ -202,7 +202,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user2Library1, managerRole)).toBeVisible();
});
test('[XAT-5140] Mark a library as favorite - from My Libraries', async () => {
test('[C289974] Mark library as favorite from My Libraries', async () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary3, contributorRole)).toBeVisible();
await libraryTable.getCellByColumnNameAndRowItem(adminLibrary3, contributorRole).click();
await myLibrariesHeader.clickMoreActions();
@ -211,7 +211,7 @@ test.describe('Library actions ', () => {
expect(await libraryMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true);
});
test('[XAT-5142] Remove a library from favorites - from My Libraries', async ({ myLibrariesPage }) => {
test('[C289975] Remove library from favorites from My Libraries', async ({ myLibrariesPage }) => {
await expect(libraryTable.getRowByName(user2Library2)).toBeVisible();
await libraryTable.getRowByName(user2Library2).click();
await myLibrariesPage.page.waitForTimeout(1000);
@ -222,7 +222,7 @@ test.describe('Library actions ', () => {
expect(await libraryMenu.isMenuItemVisible(favoriteButton)).toBe(true);
});
test('[XAT-5145] Delete a library - from My Libraries', async ({ trashPage }) => {
test('[C289988] Delete a library from My Libraries', async ({ trashPage }) => {
const trashTable = trashPage.dataTable;
await expect(libraryTable.getRowByName(user2Library5Delete)).toBeVisible();
await libraryTable.getRowByName(user2Library5Delete).click();
@ -250,7 +250,7 @@ test.describe('Library actions ', () => {
}
});
test('[XAT-5128] Join a public library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
test('[C290105] Join a public library from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
await favoritesApi.addFavoriteById(siteString, adminLibrary1);
await favoriteLibrariesPage.navigate();
await libraryTable.performActionFromExpandableMenu(adminLibrary1, joinButton);
@ -258,7 +258,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary1, consumerRole)).toBeVisible();
});
test('[XAT-5130] Join a moderated library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
test('[C290109] Join a moderated library from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
await favoritesApi.addFavoriteById(siteString, adminModerateLibrary1);
await favoriteLibrariesPage.navigate();
await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary1, notMemberString)).toBeVisible();
@ -270,7 +270,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary1, consumerRole)).toBeVisible();
});
test('[XAT-5133] Leave a library - from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
test('[C290110] Leave a library from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
const confirmDialog = favoriteLibrariesPage.confirmDialogComponent;
await favoritesApi.addFavoriteById(siteString, user1Library2);
await favoriteLibrariesPage.navigate();
@ -281,7 +281,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library2, notMemberString)).toBeVisible();
});
test('[XAT-5138] Cancel join - from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
test('[C290108] Cancel join from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModerateLibrary3);
await favoritesApi.addFavoriteById(siteString, adminModerateLibrary3);
await favoriteLibrariesPage.navigate();
@ -293,7 +293,7 @@ test.describe('Library actions ', () => {
expect(hasJoinRequest).toBe(false);
});
test('[XAT-5143] Remove a library from favorites - from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
test('[C289976] Remove library from favorites from Favorite Libraries', async ({ favoriteLibrariesPage }) => {
const myLibrariesHeader = favoriteLibrariesPage.acaHeader;
const libraryMenu = favoriteLibrariesPage.matMenu;
@ -305,7 +305,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getRowByName(user2Library3)).toBeHidden();
});
test('[XAT-5146] Delete a library - from Favorite Libraries', async ({ favoriteLibrariesPage, trashPage }) => {
test('[C289991] Delete a library from Favorite Libraries', async ({ favoriteLibrariesPage, trashPage }) => {
const myLibrariesHeader = favoriteLibrariesPage.acaHeader;
const libraryMenu = favoriteLibrariesPage.matMenu;
const trashTable = trashPage.dataTable;
@ -335,7 +335,7 @@ test.describe('Library actions ', () => {
}
});
test('[XAT-5129] Join a public library - from Search Results', async ({ searchPage }) => {
test('[C306959] Join a public library from Search Results', async ({ searchPage }) => {
await searchPage.searchWithin(adminLibrary2, 'libraries');
await searchPage.reload({ waitUntil: loadString });
await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary2, notMemberString)).toBeVisible();
@ -344,7 +344,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(adminLibrary2, consumerRole)).toBeVisible();
});
test('[XAT-5131] Join a moderated library - from Search Results', async ({ myLibrariesPage, searchPage }) => {
test('[C306960] Join a moderated library from Search Results', async ({ myLibrariesPage, searchPage }) => {
await searchPage.searchWithin(adminModerateLibrary2, 'libraries');
await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary2, notMemberString)).toBeVisible();
await libraryTable.performActionFromExpandableMenu(adminModerateLibrary2, joinButton);
@ -355,7 +355,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary2, consumerRole)).toBeVisible();
});
test('[XAT-5134] Leave a library - from Search Results', async ({ searchPage }) => {
test('[C306961] Leave a library from Search Results', async ({ searchPage }) => {
const confirmDialog = searchPage.confirmDialogComponent;
await searchPage.searchWithin(user1Library3, 'libraries');
@ -366,7 +366,7 @@ test.describe('Library actions ', () => {
await expect(libraryTable.getCellByColumnNameAndRowItem(user1Library3, notMemberString)).toBeVisible();
});
test('[XAT-5139] Cancel join - from Search Results', async ({ searchPage }) => {
test('[C306962] Cancel join from Search Results', async ({ searchPage }) => {
await user2SitesApi.createSiteMembershipRequestForPerson(username2, adminModerateLibrary4);
await searchPage.searchWithin(adminModerateLibrary4, 'libraries');
await expect(libraryTable.getCellByColumnNameAndRowItem(adminModerateLibrary4, notMemberString)).toBeVisible();
@ -376,7 +376,7 @@ test.describe('Library actions ', () => {
expect(hasJoinRequest).toBe(false);
});
test('[XAT-5141] Mark a library as favorite - from Search Results', async ({ myLibrariesPage, searchPage }) => {
test('[C306963] Mark library as favorite from Search Results', async ({ myLibrariesPage, searchPage }) => {
const myLibrariesHeader = myLibrariesPage.acaHeader;
const libraryMenu = myLibrariesPage.matMenu;
@ -393,7 +393,7 @@ test.describe('Library actions ', () => {
expect(await libraryMenu.isMenuItemVisible(removeFavoriteButton)).toBe(true);
});
test('[XAT-5144] Remove a library from favorites - from Search Results', async ({ searchPage }) => {
test('[C306964] Remove library from favorites from Search Results', async ({ searchPage }) => {
const searchHeader = searchPage.acaHeader;
const libraryMenu = searchPage.matMenu;
@ -411,7 +411,7 @@ test.describe('Library actions ', () => {
expect(await libraryMenu.isMenuItemVisible(favoriteButton)).toBe(true);
});
test('[XAT-5147] Delete a library - from Search Results', async ({ searchPage, trashPage }) => {
test('[C306965] Delete a library from Search Results', async ({ searchPage, trashPage }) => {
const searchHeader = searchPage.acaHeader;
const libraryMenu = searchPage.matMenu;
const trashTable = trashPage.dataTable;

View File

@ -1,3 +1,4 @@
{
"XAT-4525": "https://alfresco.atlassian.net/browse/AAE-7517"
"C261153": "https://alfresco.atlassian.net/browse/AAE-7517",
"C261147": "https://hyland.atlassian.net/browse/ACS-8993"
}

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*

View File

@ -1,5 +1,5 @@
/*!
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Alfresco Example Content Application
*
@ -38,57 +38,14 @@ test.describe('Empty list views', () => {
await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed');
});
async function openEmptyTab(searchPage: SearchPage, tab: string, emptyStateTitle: string, emptyStateSubtitle: string) {
await searchPage.sidenav.openPanel(tab);
await searchPage.dataTable.spinnerWaitForReload();
if (await searchPage.dataTable.isEmpty()) {
expect(await searchPage.dataTable.getEmptyStateTitle()).toContain(emptyStateTitle);
expect(await searchPage.dataTable.getEmptyStateSubtitle()).toContain(emptyStateSubtitle);
} else {
expect(await searchPage.dataTable.getRowsCount()).toEqual(1);
}
}
async function checkPaginationForTabs(searchPage: SearchPage, tab: string, personalFiles: PersonalFilesPage) {
await searchPage.sidenav.openPanel(tab);
expect(await personalFiles.pagination.isRangePresent()).toBeFalsy();
expect(await personalFiles.pagination.isMaxItemsPresent()).toBeFalsy();
expect(await personalFiles.pagination.isCurrentPagePresent()).toBeFalsy();
expect(await personalFiles.pagination.isTotalPagesPresent()).toBeFalsy();
expect(await personalFiles.pagination.isPreviousButtonPresent()).toBeFalsy();
expect(await personalFiles.pagination.isNextButtonPresent()).toBeFalsy();
}
test('[XAT-4402] Empty My Libraries', async ({ myLibrariesPage }) => {
test('[C217099] empty My Libraries', async ({ myLibrariesPage }) => {
await myLibrariesPage.navigate();
expect(await myLibrariesPage.dataTable.isEmpty(), 'list is not empty').toBe(true);
expect(await myLibrariesPage.dataTable.getEmptyStateTitle()).toContain(`You aren't a member of any File Libraries yet`);
expect(await myLibrariesPage.dataTable.getEmptyStateSubtitle()).toContain('Join libraries to upload, view, and share files.');
});
test(`[XAT-4403] Empty Favorite Libraries`, async ({ searchPage }) => {
await openEmptyTab(
searchPage,
SIDEBAR_LABELS.FAVORITE_LIBRARIES,
'No Favorite Libraries',
'Favorite a library that you want to find easily later.'
);
});
test(`[XAT-4405] Empty Recent Files`, async ({ searchPage }) => {
await openEmptyTab(
searchPage,
SIDEBAR_LABELS.RECENT_FILES,
'No recent files',
'Items you uploaded or edited in the last 30 days are shown here.'
);
});
test(`[XAT-4406] Empty Favorites`, async ({ searchPage }) => {
await openEmptyTab(searchPage, SIDEBAR_LABELS.FAVORITES, 'No favorite files or folders', 'Favorite items that you want to easily find later.');
});
test('[XAT-4581] Trash - Pagination control is not displayed on empty page load', async ({ trashPage }) => {
test('[C280134] [C280120] Empty Trash - pagination controls not displayed', async ({ trashPage }) => {
await trashPage.navigate();
expect(await trashPage.dataTable.isEmpty(), 'list is not empty').toBe(true);
expect(await trashPage.dataTable.getEmptyStateTitle()).toContain('Trash is empty');
@ -98,7 +55,7 @@ test.describe('Empty list views', () => {
expect(await trashPage.pagination.isMaxItemsPresent(), 'Max items is present').toBe(false);
});
test('[XAT-4590] Search Page - Pagination control is not displayed on empty page load', async ({ personalFiles, searchPage }) => {
test('[C290123] [C290031] Empty Search results - pagination controls not displayed', async ({ personalFiles, searchPage }) => {
await personalFiles.acaHeader.searchButton.click();
await searchPage.clickSearchButton();
await searchPage.searchOverlay.checkFilesAndFolders();
@ -112,23 +69,85 @@ test.describe('Empty list views', () => {
expect(await personalFiles.dataTable.emptySearchText.innerText()).toContain('Your search returned 0 results');
});
test(`[XAT-4573] Favorites - Pagination control is not displayed on empty page load`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, SIDEBAR_LABELS.FAVORITES, personalFiles);
test('[C290020] Empty Search results - Libraries', async ({ searchPage }) => {
await searchPage.sidenav.openPanel(SIDEBAR_LABELS.MY_LIBRARIES);
/* cspell:disable-next-line */
await searchPage.searchWithin('qwertyuiop', 'files');
expect(await searchPage.dataTable.isEmpty()).toBeTruthy();
expect(await searchPage.dataTable.emptySearchText.textContent()).toContain('Your search returned 0 results');
});
test(`[XAT-4537] My Libraries - Pagination control is not displayed on empty page load`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, SIDEBAR_LABELS.MY_LIBRARIES, personalFiles);
async function openEmptyTab(searchPage: SearchPage, tab: string, emptyStateTitle: string, emptyStateSubtitle: string) {
await searchPage.sidenav.openPanel(tab);
expect(await searchPage.dataTable.isEmpty()).toBeTruthy();
expect(await searchPage.dataTable.getEmptyStateTitle()).toContain(emptyStateTitle);
expect(await searchPage.dataTable.getEmptyStateSubtitle()).toContain(emptyStateSubtitle);
}
[
{
tab: SIDEBAR_LABELS.FAVORITE_LIBRARIES,
id: 'C289911',
emptyStateTitle: `No Favorite Libraries`,
emptyStateSubtitle: 'Favorite a library that you want to find easily later.'
},
{
tab: SIDEBAR_LABELS.RECENT_FILES,
id: 'C213169',
emptyStateTitle: 'No recent files',
emptyStateSubtitle: 'Items you uploaded or edited in the last 30 days are shown here.'
},
{
tab: SIDEBAR_LABELS.FAVORITES,
id: 'C280133',
emptyStateTitle: 'No favorite files or folders',
emptyStateSubtitle: 'Favorite items that you want to easily find later.'
}
].forEach((testCase) => {
test(`[${testCase.id}] empty ${testCase.tab}`, async ({ searchPage }) => {
await openEmptyTab(searchPage, testCase.tab, testCase.emptyStateTitle, testCase.emptyStateSubtitle);
});
});
test(`[XAT-4546] Favorite Libraries - Pagination control is not displayed on empty page load`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, SIDEBAR_LABELS.FAVORITE_LIBRARIES, personalFiles);
});
async function checkPaginationForTabs(searchPage: SearchPage, tab: string, personalFiles: PersonalFilesPage) {
await searchPage.sidenav.openPanel(tab);
expect(await personalFiles.pagination.isRangePresent()).toBeFalsy();
expect(await personalFiles.pagination.isMaxItemsPresent()).toBeFalsy();
expect(await personalFiles.pagination.isCurrentPagePresent()).toBeFalsy();
expect(await personalFiles.pagination.isTotalPagesPresent()).toBeFalsy();
expect(await personalFiles.pagination.isPreviousButtonPresent()).toBeFalsy();
expect(await personalFiles.pagination.isNextButtonPresent()).toBeFalsy();
}
test(`[XAT-4528] Personal Files - Pagination control is not displayed on empty page load`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, SIDEBAR_LABELS.PERSONAL_FILES, personalFiles);
[
{
tab: SIDEBAR_LABELS.FAVORITES,
id: 'C280111'
},
{
tab: SIDEBAR_LABELS.MY_LIBRARIES,
id: 'C280084'
},
{
tab: SIDEBAR_LABELS.FAVORITE_LIBRARIES,
id: 'C291873'
},
{
tab: SIDEBAR_LABELS.PERSONAL_FILES,
id: 'C280075'
},
{
tab: SIDEBAR_LABELS.RECENT_FILES,
id: 'C280102'
},
{
tab: SIDEBAR_LABELS.TRASH,
id: 'C280120'
}
].forEach((testCase) => {
test(`[${testCase.id}] ${testCase.tab} - pagination controls not displayed`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, testCase.tab, personalFiles);
});
test(`[XAT-4564] Recent Files - Pagination control is not displayed on empty page load`, async ({ searchPage, personalFiles }) => {
await checkPaginationForTabs(searchPage, SIDEBAR_LABELS.RECENT_FILES, personalFiles);
});
});

Some files were not shown because too many files have changed in this diff Show More