mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACA-1843] tomcat e2e runs (#674)
* tomcat environment * disable artifact deployment for now * travis settings update * protractor settings * protractor settings * e2e fixes * e2e fixes * [ACA-1842] fix library dialog * cleanup travis settings * disable test (bug raised) * fix after rebase * fix after rebase
This commit is contained in:
parent
25e6f15ffc
commit
93e6489881
17
.travis.yml
17
.travis.yml
@ -30,18 +30,9 @@ jobs:
|
||||
script:
|
||||
- npm run test:ci
|
||||
- bash <(curl -s https://codecov.io/bash) -X gcov
|
||||
before_deploy: 'npm run build.tomcat'
|
||||
deploy:
|
||||
provider: s3
|
||||
region: $ARTIFACTS_REGION
|
||||
access_key_id: $ARTIFACTS_KEY
|
||||
secret_access_key: $ARTIFACTS_SECRET
|
||||
bucket: $ARTIFACTS_BUCKET
|
||||
skip_cleanup: true
|
||||
local-dir: dist/tomcat
|
||||
upload-dir: ${TRAVIS_BUILD_NUMBER}/tomcat
|
||||
on:
|
||||
repo: Alfresco/alfresco-content-app
|
||||
branch: development
|
||||
- stage: e2e
|
||||
name: 'Nginx'
|
||||
script: npm run build && npm run e2e:docker
|
||||
- stage: e2e
|
||||
name: 'Tomcat'
|
||||
script: npm run build.tomcat && npm run docker.tomcat.e2e
|
||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -1,6 +1,8 @@
|
||||
{
|
||||
"javascript.preferences.quoteStyle": "single",
|
||||
"javascript.preferences.importModuleSpecifier": "relative",
|
||||
"typescript.preferences.quoteStyle": "single",
|
||||
"typescript.preferences.importModuleSpecifier": "relative",
|
||||
"editor.formatOnSave": true,
|
||||
"[html]": {
|
||||
"editor.formatOnSave": false
|
||||
|
5
docker/tomcat/Dockerfile
Normal file
5
docker/tomcat/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM tomcat
|
||||
LABEL version="1.3"
|
||||
LABEL maintainer="Denys Vuika <denys.vuika@alfresco.com>"
|
||||
|
||||
COPY ./artifacts/content-app.war /usr/local/tomcat/webapps/content-app.war
|
1
docker/tomcat/artifacts/.gitignore
vendored
Normal file
1
docker/tomcat/artifacts/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.war
|
0
docker/tomcat/artifacts/.gitkeep
Normal file
0
docker/tomcat/artifacts/.gitkeep
Normal file
95
docker/tomcat/docker-compose.yml
Normal file
95
docker/tomcat/docker-compose.yml
Normal file
@ -0,0 +1,95 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
alfresco:
|
||||
image: alfresco/alfresco-content-repository-community:6.0.7-ga
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
JAVA_OPTS: '
|
||||
-Ddb.driver=org.postgresql.Driver
|
||||
-Ddb.username=alfresco
|
||||
-Ddb.password=alfresco
|
||||
-Ddb.url=jdbc:postgresql://postgres:5432/alfresco
|
||||
-Dsolr.host=solr6
|
||||
-Dsolr.port=8983
|
||||
-Dsolr.secureComms=none
|
||||
-Dsolr.base.url=/solr
|
||||
-Dindex.subsystem.name=solr6
|
||||
-Dshare.host=localhost
|
||||
-Ddeployment.method=DOCKER_COMPOSE
|
||||
-Dcsrf.filter.enabled=false
|
||||
'
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 8080:8080 #Browser port
|
||||
|
||||
share:
|
||||
image: alfresco/alfresco-share:6.0.b
|
||||
depends_on:
|
||||
- alfresco
|
||||
environment:
|
||||
- REPO_HOST=alfresco
|
||||
- REPO_PORT=8080
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 8083:8080
|
||||
|
||||
postgres:
|
||||
image: postgres:10.1
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=alfresco
|
||||
- POSTGRES_USER=alfresco
|
||||
- POSTGRES_DB=alfresco
|
||||
command: postgres -c max_connections=300 -c log_min_messages=LOG
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
solr6:
|
||||
image: alfresco/alfresco-search-services:1.1.1
|
||||
depends_on:
|
||||
- alfresco
|
||||
environment:
|
||||
#Solr needs to know how to register itself with Alfresco
|
||||
- SOLR_ALFRESCO_HOST=alfresco
|
||||
- SOLR_ALFRESCO_PORT=8080
|
||||
#Alfresco needs to know how to call solr
|
||||
- SOLR_SOLR_HOST=solr6
|
||||
- SOLR_SOLR_PORT=8983
|
||||
#Create the default alfresco and archive cores
|
||||
- SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 8983:8983 #Browser port
|
||||
|
||||
content-app:
|
||||
image: alfresco/alfresco-content-app:development-latest-tomcat8
|
||||
build: .
|
||||
depends_on:
|
||||
- alfresco
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 4001:8080
|
||||
# volumes:
|
||||
# - ./app.config.json:/usr/share/nginx/html/app.config.json
|
||||
# - ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
|
||||
proxy:
|
||||
image: nginx
|
||||
depends_on:
|
||||
- content-app
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
networks:
|
||||
- internal
|
||||
ports:
|
||||
- 4000:80
|
||||
|
||||
networks:
|
||||
? internal
|
43
docker/tomcat/nginx.conf
Normal file
43
docker/tomcat/nginx.conf
Normal file
@ -0,0 +1,43 @@
|
||||
server {
|
||||
listen *:80;
|
||||
|
||||
set $allowOriginSite *;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_pass_header Set-Cookie;
|
||||
|
||||
location / {
|
||||
proxy_pass http://content-app:8080;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass_header Set-Cookie;
|
||||
}
|
||||
|
||||
location /alfresco/ {
|
||||
proxy_pass http://alfresco:8080;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass_header Set-Cookie;
|
||||
}
|
||||
|
||||
location /share/ {
|
||||
proxy_pass http://share:8080;
|
||||
|
||||
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_pass_header Set-Cookie;
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ export const BROWSER_RESOLUTION_HEIGHT = 800;
|
||||
export const BROWSER_WAIT_TIMEOUT = 10000;
|
||||
|
||||
// Application configs
|
||||
export const APP_HOST = 'http://localhost:4000';
|
||||
export const USE_HASH_STRATEGY = true;
|
||||
|
||||
// Repository configs
|
||||
export const REPO_API_HOST = 'http://localhost:8080';
|
||||
|
@ -31,11 +31,9 @@ import {
|
||||
promise,
|
||||
ExpectedConditions as EC
|
||||
} from 'protractor';
|
||||
import { BROWSER_WAIT_TIMEOUT } from './../configs';
|
||||
import { BROWSER_WAIT_TIMEOUT, USE_HASH_STRATEGY } from './../configs';
|
||||
|
||||
export abstract class Page {
|
||||
private static USE_HASH_STRATEGY = true;
|
||||
|
||||
private locators = {
|
||||
app: by.css('app-root'),
|
||||
layout: by.css('app-layout'),
|
||||
@ -69,8 +67,8 @@ export abstract class Page {
|
||||
}
|
||||
|
||||
load(relativeUrl: string = ''): promise.Promise<void> {
|
||||
const hash = Page.USE_HASH_STRATEGY ? '/#' : '';
|
||||
const path = `${hash}${this.url}${relativeUrl}`;
|
||||
const hash = USE_HASH_STRATEGY ? '/#' : '';
|
||||
const path = `${browser.baseUrl}${hash}${this.url}${relativeUrl}`;
|
||||
|
||||
return browser.get(path);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import { APP_ROUTES } from '../../configs';
|
||||
import { LoginPage, LogoutPage, BrowsingPage } from '../../pages/pages';
|
||||
import { Utils } from '../../utilities/utils';
|
||||
import { RepoClient } from '../../utilities/repo-client/repo-client';
|
||||
import { navigate } from '../../utilities/browser-utils';
|
||||
|
||||
describe('Login', () => {
|
||||
const peopleApi = new RepoClient().people;
|
||||
@ -128,11 +129,12 @@ describe('Login', () => {
|
||||
expect(browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
|
||||
it('redirects to Home Page when navigating to the Login page while already logged in - [C213107]', async () => {
|
||||
xit('redirects to Home Page when navigating to the Login page while already logged in - [C213107]', async () => {
|
||||
const { username } = johnDoe;
|
||||
|
||||
await loginPage.loginWith(username);
|
||||
await browser.get(APP_ROUTES.LOGIN);
|
||||
|
||||
await navigate(APP_ROUTES.LOGIN);
|
||||
expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.PERSONAL_FILES);
|
||||
});
|
||||
|
||||
@ -189,7 +191,7 @@ describe('Login', () => {
|
||||
});
|
||||
|
||||
it('unauthenticated user is redirected to Login page - [C213106]', async () => {
|
||||
await browser.get(APP_ROUTES.PERSONAL_FILES);
|
||||
await navigate(APP_ROUTES.PERSONAL_FILES);
|
||||
expect(await browser.getCurrentUrl()).toContain(APP_ROUTES.LOGIN);
|
||||
});
|
||||
|
||||
|
39
e2e/utilities/browser-utils.ts
Normal file
39
e2e/utilities/browser-utils.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
*
|
||||
* 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
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { browser } from 'protractor';
|
||||
import { USE_HASH_STRATEGY } from '../configs';
|
||||
|
||||
export async function navigate(relativePath: string) {
|
||||
const path = [
|
||||
browser.baseUrl,
|
||||
browser.baseUrl.endsWith('/') ? '' : '/',
|
||||
USE_HASH_STRATEGY ? '#' : '',
|
||||
relativePath.startsWith('/') ? '' : '/',
|
||||
relativePath
|
||||
].join('');
|
||||
|
||||
return browser.get(path);
|
||||
}
|
@ -15,15 +15,18 @@
|
||||
"__e2e": "ng e2e",
|
||||
"__wd:update": "webdriver-manager update --gecko=false --versions.chrome=2.38",
|
||||
"wd:update": "webdriver-manager update --gecko=false",
|
||||
"e2e": "npm run wd:update && protractor protractor.conf.js",
|
||||
"e2e": "npm run wd:update && protractor --baseUrl=http://localhost:4000",
|
||||
"start:docker": "docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000",
|
||||
"stop:docker": "docker-compose stop",
|
||||
"e2e:docker": "npm run start:docker && npm run e2e && npm run stop:docker",
|
||||
"spellcheck": "cspell 'src/**/*.ts' 'e2e/**/*.ts' 'projects/**/*.ts'",
|
||||
"inspect.bundle": "ng build app --prod --stats-json && npx webpack-bundle-analyzer dist/app/stats.json",
|
||||
"format:check": "prettier --list-different \"src/{app,environments}/**/*{.ts,.js,.css,.scss}\"",
|
||||
"build.tomcat": "npm run build -- --base-href ./ && mkdir -p dist/tomcat && jar -cvf dist/tomcat/content-app.war -C dist/app/ .",
|
||||
"start.tomcat": "docker run -v `pwd`/dist/tomcat/content-app.war:/usr/local/tomcat/webapps/content-app.war -it -p 4080:8080 tomcat || exit 0"
|
||||
"build.tomcat": "npm run build -- --base-href ./ && jar -cvf docker/tomcat/artifacts/content-app.war -C dist/app/ .",
|
||||
"e2e.tomcat": "npm run wd:update && protractor --baseUrl=http://localhost:4000/content-app/",
|
||||
"docker.tomcat.start": "cd docker/tomcat && docker-compose up -d --build && wait-on http://localhost:8080 && wait-on http://localhost:4000",
|
||||
"docker.tomcat.stop": "cd docker/tomcat && docker-compose stop",
|
||||
"docker.tomcat.e2e": "npm run docker.tomcat.start && npm run e2e.tomcat"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
@ -2,9 +2,7 @@
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const path = require('path');
|
||||
const {
|
||||
SpecReporter
|
||||
} = require('jasmine-spec-reporter');
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
const jasmineReporters = require('jasmine-reporters');
|
||||
const CDP = require('chrome-remote-interface');
|
||||
|
||||
@ -25,13 +23,11 @@ function rmDir(dirPath) {
|
||||
if (files.length > 0)
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var filePath = dirPath + '/' + files[i];
|
||||
if (fs.statSync(filePath).isFile())
|
||||
fs.unlinkSync(filePath);
|
||||
else
|
||||
rmDir(filePath);
|
||||
if (fs.statSync(filePath).isFile()) fs.unlinkSync(filePath);
|
||||
else rmDir(filePath);
|
||||
}
|
||||
fs.rmdirSync(dirPath);
|
||||
};
|
||||
}
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 40000,
|
||||
@ -56,10 +52,10 @@ exports.config = {
|
||||
browserName: 'chrome',
|
||||
chromeOptions: {
|
||||
prefs: {
|
||||
'credentials_enable_service': false,
|
||||
'download': {
|
||||
'prompt_for_download': false,
|
||||
'default_directory': downloadFolder
|
||||
credentials_enable_service: false,
|
||||
download: {
|
||||
prompt_for_download: false,
|
||||
default_directory: downloadFolder
|
||||
}
|
||||
},
|
||||
args: ['--incognito', '--headless', '--remote-debugging-port=9222']
|
||||
@ -68,7 +64,7 @@ exports.config = {
|
||||
|
||||
directConnect: true,
|
||||
|
||||
baseUrl: 'http://localhost:4000',
|
||||
// baseUrl: 'http://localhost:4000',
|
||||
|
||||
framework: 'jasmine2',
|
||||
jasmineNodeOpts: {
|
||||
@ -77,7 +73,8 @@ exports.config = {
|
||||
print: function() {}
|
||||
},
|
||||
|
||||
plugins: [{
|
||||
plugins: [
|
||||
{
|
||||
package: 'jasmine2-protractor-utils',
|
||||
disableHTMLReport: false,
|
||||
disableScreenshot: false,
|
||||
@ -86,40 +83,49 @@ exports.config = {
|
||||
clearFoldersBeforeTest: true,
|
||||
htmlReportDir: `${projectRoot}/e2e-output/html-report/`,
|
||||
screenshotPath: `${projectRoot}/e2e-output/screenshots/`
|
||||
}],
|
||||
}
|
||||
],
|
||||
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
|
||||
browser.manage().window().setSize(width, height);
|
||||
browser
|
||||
.manage()
|
||||
.window()
|
||||
.setSize(width, height);
|
||||
|
||||
jasmine.getEnv().addReporter(new SpecReporter({
|
||||
jasmine.getEnv().addReporter(
|
||||
new SpecReporter({
|
||||
spec: {
|
||||
displayStacktrace: true
|
||||
}
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
|
||||
jasmine.getEnv().addReporter(
|
||||
new jasmineReporters.JUnitXmlReporter({
|
||||
consolidateAll: true,
|
||||
savePath: `${projectRoot}/e2e-output/junit-report`,
|
||||
filePrefix: 'results.xml',
|
||||
useDotNotation: false,
|
||||
useFullTestName: false,
|
||||
reportFailedUrl: true
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
rmDir(downloadFolder);
|
||||
|
||||
CDP().then(client => {
|
||||
CDP()
|
||||
.then(client => {
|
||||
client.send('Page.setDownloadBehavior', {
|
||||
behavior: 'allow',
|
||||
downloadPath: downloadFolder
|
||||
})
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -234,7 +234,7 @@ export class ContentManagementService {
|
||||
});
|
||||
}
|
||||
|
||||
createLibrary(): Observable<SiteEntry> {
|
||||
createLibrary(): Observable<string> {
|
||||
const dialogInstance = this.dialogRef.open(LibraryDialogComponent, {
|
||||
width: '400px'
|
||||
});
|
||||
@ -243,9 +243,19 @@ export class ContentManagementService {
|
||||
this.store.dispatch(new SnackbarErrorAction(message));
|
||||
});
|
||||
|
||||
return dialogInstance
|
||||
.afterClosed()
|
||||
.pipe(tap(node => this.libraryCreated.next(node)));
|
||||
return dialogInstance.afterClosed().pipe(
|
||||
tap(node => {
|
||||
if (node) {
|
||||
this.libraryCreated.next(node);
|
||||
}
|
||||
}),
|
||||
map((node: SiteEntry) => {
|
||||
if (node && node.entry && node.entry.guid) {
|
||||
return node.entry.guid;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
deleteLibrary(id: string): void {
|
||||
|
@ -74,7 +74,7 @@ export class LibraryEffects {
|
||||
createLibrary$ = this.actions$.pipe(
|
||||
ofType<CreateLibraryAction>(CREATE_LIBRARY),
|
||||
mergeMap(() => this.content.createLibrary()),
|
||||
map(node => new NavigateLibraryAction(node.entry.guid))
|
||||
map(libraryId => new NavigateLibraryAction(libraryId))
|
||||
);
|
||||
|
||||
@Effect({ dispatch: false })
|
||||
|
Loading…
x
Reference in New Issue
Block a user