[ACS-6572] break dependency on adf-testing (#3594)

* remove Logger dependency

* remove BrowserVisibility dependency

* remove BrowserActions dependency

* remove ViewerPage dependency

* remove ApiUtil dependency

* remove StringUtil dependency

* remove adf-testing dependency

* bug fixes
This commit is contained in:
Denys Vuika 2024-01-11 09:02:58 -05:00 committed by GitHub
parent 09aba59b06
commit dbe724552f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 871 additions and 538 deletions

View File

@ -24,7 +24,6 @@
import { ApiClientFactory, test, Utils, PersonalFilesPage, NodesApi, LoginPage } from '@alfresco/playwright-shared';
import { expect } from '@playwright/test';
import { Logger } from '@alfresco/adf-testing';
test.describe('Copy actions', () => {
let nodesApi: NodesApi;
@ -45,17 +44,13 @@ test.describe('Copy actions', () => {
await apiClientFactory.setUpAcaBackend('admin');
await apiClientFactory.createUser({ username });
nodesApi = await NodesApi.initialize(username, username);
} catch (error) {
Logger.error(`beforeAll failed : ${error}`);
}
} catch {}
});
test.afterAll(async ({ nodesApiAction }) => {
try {
await nodesApiAction.deleteCurrentUserNodes();
} catch (error) {
Logger.error(`afterAll failed : ${error}`);
}
} catch {}
});
test.beforeEach(async ({ personalFiles, page }) => {
@ -79,9 +74,7 @@ test.describe('Copy actions', () => {
sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
await personalFiles.navigate();
} catch (error) {
Logger.error(`beforeEach failed : ${error}`);
}
} catch {}
});
const copyContentInPersonalFiles = async (personalFilesPage: PersonalFilesPage, sourceFileList: string[], destinationName: string) => {

View File

@ -25,7 +25,6 @@
import { ApiClientFactory, MyLibrariesPage, NodesApi, SitesApi, test, Utils } from '@alfresco/playwright-shared';
import { expect } from '@playwright/test';
import { Site } from '@alfresco/js-api';
import { Logger } from '@alfresco/adf-testing';
test.describe('Copy Move actions', () => {
let nodesApi: NodesApi;
@ -63,18 +62,14 @@ test.describe('Copy Move actions', () => {
await nodesApi.createFile(sourceFile, docLibId);
await nodesApi.createFolder(destinationFolder, docLibId);
} catch (error) {
Logger.error(`beforeAll failed : ${error}`);
}
} catch {}
});
test.afterAll(async () => {
try {
await nodesApi.deleteCurrentUserNodes();
await sitesApi.deleteSites([siteId]);
} catch (error) {
Logger.error(`afterAll failed : ${error}`);
}
} catch {}
});
const copyContentInMyLibraries = async (myLibrariesPage: MyLibrariesPage) => {

View File

@ -24,7 +24,6 @@
import { ApiClientFactory, test, Utils, PersonalFilesPage, NodesApi, LoginPage } from '@alfresco/playwright-shared';
import { expect } from '@playwright/test';
import { Logger } from '@alfresco/adf-testing';
test.describe('Move actions', () => {
let nodesApi: NodesApi;
@ -45,17 +44,13 @@ test.describe('Move actions', () => {
await apiClientFactory.setUpAcaBackend('admin');
await apiClientFactory.createUser({ username });
nodesApi = await NodesApi.initialize(username, username);
} catch (error) {
Logger.error(`beforeAll failed : ${error}`);
}
} catch {}
});
test.afterAll(async ({ nodesApiAction }) => {
try {
await nodesApiAction.deleteCurrentUserNodes();
} catch (error) {
Logger.error(`afterAll failed : ${error}`);
}
} catch {}
});
test.beforeEach(async ({ personalFiles, page }) => {
@ -79,9 +74,7 @@ test.describe('Move actions', () => {
sourceFileId = (await nodesApi.createFile(sourceFile)).entry.id;
await personalFiles.navigate();
} catch (error) {
Logger.error(`beforeEach failed : ${error}`);
}
} catch {}
});
const moveContentInPersonalFiles = async (personalFilesPage: PersonalFilesPage, sourceFileList: string[], destinationName: string) => {

View File

@ -25,7 +25,6 @@
import { expect } from '@playwright/test';
import { ApiClientFactory, FileActionsApi, LoginPage, NodesApi, SitesApi, test, TEST_FILES, Utils } from '@alfresco/playwright-shared';
import { SiteBodyCreate } from '@alfresco/js-api';
import { Logger } from '@alfresco/adf-testing';
test.describe('from File Libraries', () => {
const apiClientFactory = new ApiClientFactory();
@ -50,9 +49,7 @@ test.describe('from File Libraries', () => {
const node = await nodesApi.createFolder(destination);
destinationId = node.entry.id;
await fileApi.uploadFile(TEST_FILES.XLSX.path, xlsxLibraries, docLibId);
} catch (error) {
Logger.error(`beforeAll failed : ${error}`);
}
} catch {}
});
test.beforeEach(async ({ page }) => {
@ -70,9 +67,7 @@ test.describe('from File Libraries', () => {
try {
await sitesApi.deleteSites([siteName]);
await nodesApi.deleteNodes([destinationId]);
} catch (error) {
Logger.error(`afterAll failed : ${error}`);
}
} catch {}
});
test('[C286371] Move action from File Libraries', async ({ myLibrariesPage, personalFiles }) => {

View File

@ -23,7 +23,6 @@
*/
import { AdminActions, UserActions, LoginPage, BrowsingPage, RepoClient, Utils } from '@alfresco/aca-testing-shared';
import { Logger } from '@alfresco/adf-testing';
describe('Delete and undo delete', () => {
const username = `user-${Utils.random()}`;
@ -120,9 +119,7 @@ describe('Delete and undo delete', () => {
await userActions.unlockNodes([fileLocked1Id, fileLocked2Id, fileLocked3Id, fileLocked4Id]);
await userActions.deleteNodes([parentId]);
await userActions.emptyTrashcan();
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
it('[C217125] delete a file and check notification', async () => {

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, UserActions, LoginPage, BrowsingPage, ConfirmDialog, RepoClient, Utils } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import { AdminActions, UserActions, LoginPage, BrowsingPage, ConfirmDialog, RepoClient, Utils, click } from '@alfresco/aca-testing-shared';
describe('Permanently delete from Trash', () => {
const username = `user-${Utils.random()}`;
@ -54,8 +53,8 @@ describe('Permanently delete from Trash', () => {
beforeAll(async () => {
await adminApiActions.createUser({ username });
filesIds = (await apis.user.nodes.createFiles([file1, file2, file3])).list.entries.map((entries: any) => entries.entry.id);
foldersIds = (await apis.user.nodes.createFolders([folder1, folder2])).list.entries.map((entries: any) => entries.entry.id);
filesIds = (await apis.user.nodes.createFiles([file1, file2, file3])).list.entries.map((entries) => entries.entry.id);
foldersIds = (await apis.user.nodes.createFolders([folder1, folder2])).list.entries.map((entries) => entries.entry.id);
await apis.user.sites.createSite(site);
await userActions.login(username, username);
@ -76,9 +75,9 @@ describe('Permanently delete from Trash', () => {
it('[C217091] delete a file', async () => {
await dataTable.selectItem(file1);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
await BrowserActions.click(confirmDialog.deleteButton);
await click(confirmDialog.deleteButton);
expect(await page.getSnackBarMessage()).toEqual(`${file1} deleted`);
expect(await dataTable.isItemPresent(file1)).toBe(false, 'Item was not deleted');
@ -86,9 +85,9 @@ describe('Permanently delete from Trash', () => {
it('[C280416] delete a folder', async () => {
await dataTable.selectItem(folder1);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
await BrowserActions.click(confirmDialog.deleteButton);
await click(confirmDialog.deleteButton);
expect(await page.getSnackBarMessage()).toEqual(`${folder1} deleted`);
expect(await dataTable.isItemPresent(folder1)).toBe(false, 'Item was not deleted');
@ -96,9 +95,9 @@ describe('Permanently delete from Trash', () => {
it('[C290103] delete a library', async () => {
await dataTable.selectItem(site);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
await BrowserActions.click(confirmDialog.deleteButton);
await click(confirmDialog.deleteButton);
expect(await page.getSnackBarMessage()).toEqual(`${site} deleted`);
expect(await dataTable.isItemPresent(site)).toBe(false, `${site} was not deleted`);
@ -106,9 +105,9 @@ describe('Permanently delete from Trash', () => {
it('[C280417] delete multiple items', async () => {
await dataTable.selectMultipleItems([file2, folder2]);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
await BrowserActions.click(confirmDialog.deleteButton);
await click(confirmDialog.deleteButton);
expect(await page.getSnackBarMessage()).toEqual(`2 items deleted`);
expect(await dataTable.isItemPresent(file2)).toBe(false, 'Item was not deleted');
@ -117,7 +116,7 @@ describe('Permanently delete from Trash', () => {
it('[C269113] Confirmation dialog UI', async () => {
await dataTable.selectItem(file3);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
expect(await confirmDialog.isDialogOpen()).toBe(true, 'Confirm delete dialog not open');
@ -132,11 +131,11 @@ describe('Permanently delete from Trash', () => {
it('[C269115] Keep action cancels the deletion', async () => {
await dataTable.selectItem(file3);
await BrowserActions.click(toolbar.permanentlyDeleteButton);
await click(toolbar.permanentlyDeleteButton);
await page.waitForDialog();
expect(await confirmDialog.isKeepEnabled()).toBe(true, 'KEEP button is not enabled');
await BrowserActions.click(confirmDialog.keepButton);
await click(confirmDialog.keepButton);
expect(await dataTable.isItemPresent(file3)).toBe(true, 'Item was deleted');
});
});

View File

@ -23,8 +23,7 @@
*/
import { browser } from 'protractor';
import { AdminActions, UserActions, LoginPage, BrowsingPage, APP_ROUTES, RepoClient, Utils } from '@alfresco/aca-testing-shared';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { AdminActions, UserActions, LoginPage, BrowsingPage, APP_ROUTES, RepoClient, Utils, click } from '@alfresco/aca-testing-shared';
describe('Restore from Trash', () => {
const username = `user-${Utils.random()}`;
@ -77,7 +76,7 @@ describe('Restore from Trash', () => {
it('[C217177] restore file', async () => {
await dataTable.selectItem(file);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
const text = await page.getSnackBarMessage();
expect(text).toContain(`${file} restored`);
const action = await page.getSnackBarAction();
@ -91,7 +90,7 @@ describe('Restore from Trash', () => {
it('[C280438] restore folder', async () => {
await dataTable.selectItem(folder);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
const text = await page.getSnackBarMessage();
expect(text).toContain(`${folder} restored`);
const action = await page.getSnackBarAction();
@ -105,7 +104,7 @@ describe('Restore from Trash', () => {
it('[C290104] restore library', async () => {
await dataTable.selectItem(site);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
const text = await page.getSnackBarMessage();
expect(text).toContain(`${site} restored`);
const action = await page.getSnackBarAction();
@ -117,7 +116,7 @@ describe('Restore from Trash', () => {
it('[C217182] restore multiple items', async () => {
await dataTable.selectMultipleItems([file, folder]);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
const text = await page.getSnackBarMessage();
expect(text).toContain(`Restore successful`);
const action = await page.getSnackBarAction();
@ -133,7 +132,7 @@ describe('Restore from Trash', () => {
it('[C217181] View from notification', async () => {
await dataTable.selectItem(file);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
await page.clickSnackBarAction();
await page.dataTable.waitForHeader();
expect(await page.sidenav.isActive('Personal Files')).toBe(true, 'Personal Files sidebar link not active');
@ -181,13 +180,13 @@ describe('Restore from Trash', () => {
it('[C217178] Restore a file when another file with same name exists on the restore location', async () => {
await dataTable.selectItem(file1);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
expect(await page.getSnackBarMessage()).toEqual(`Can't restore, ${file1} already exists`);
});
it('[C217179] Restore a file when original location no longer exists', async () => {
await dataTable.selectItem(file2);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
expect(await page.getSnackBarMessage()).toEqual(`Can't restore ${file2}, the original location no longer exists`);
});
});
@ -231,9 +230,7 @@ describe('Restore from Trash', () => {
await userActions.deleteNodes([file3Id, file4Id, folder3Id, file5Id], false);
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {
@ -247,13 +244,13 @@ describe('Restore from Trash', () => {
it('[C217183] one failure', async () => {
await dataTable.selectMultipleItems([file1, file2]);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
expect(await page.getSnackBarMessage()).toEqual(`Can't restore ${file1}, the original location no longer exists`);
});
it('[C217184] multiple failures', async () => {
await dataTable.selectMultipleItems([file3, file4, file5]);
await BrowserActions.click(toolbar.restoreButton);
await click(toolbar.restoreButton);
expect(await page.getSnackBarMessage()).toEqual('2 items not restored because of issues with the restore location');
});
});

View File

@ -31,9 +31,9 @@ import {
RepoClient,
CreateOrEditFolderDialog,
Utils,
clearTextWithBackspace
clearTextWithBackspace,
click
} from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
describe('Edit folder', () => {
const username = `user-${Utils.random()}`;
@ -133,7 +133,7 @@ describe('Edit folder', () => {
await dataTable.doubleClickOnRowByName(parent);
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
expect(await editDialog.getDialogTitle()).toEqual('Edit folder');
expect(await editDialog.getName()).toBe(folderName);
@ -152,11 +152,11 @@ describe('Edit folder', () => {
it('[C216335] properties are modified when pressing OK', async () => {
await dataTable.selectItem(folderNameToEdit);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await editDialog.waitForDialogToOpen();
await editDialog.enterDescription(folderDescriptionEdited);
await editDialog.enterName(folderNameEdited);
await BrowserActions.click(editDialog.updateButton);
await click(editDialog.updateButton);
await editDialog.waitForDialogToClose();
await dataTable.waitForHeader();
@ -168,7 +168,7 @@ describe('Edit folder', () => {
it('[C216332] with empty folder name', async () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await clearTextWithBackspace(editDialog.nameInput);
expect(await editDialog.isUpdateButtonEnabled()).toBe(false, 'upload button is not enabled');
@ -180,7 +180,7 @@ describe('Edit folder', () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
for (const name of namesWithSpecialChars) {
await editDialog.enterName(name);
@ -192,7 +192,7 @@ describe('Edit folder', () => {
it('[C216334] with name ending with a dot', async () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await editDialog.waitForDialogToOpen();
await editDialog.nameInput.sendKeys('.');
@ -203,7 +203,7 @@ describe('Edit folder', () => {
it('[C216336] Cancel button', async () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await editDialog.waitForDialogToOpen();
await editDialog.clickCancel();
@ -213,10 +213,10 @@ describe('Edit folder', () => {
it('[C216337] with duplicate folder name', async () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await editDialog.waitForDialogToOpen();
await editDialog.enterName(duplicateFolderName);
await BrowserActions.click(editDialog.updateButton);
await click(editDialog.updateButton);
expect(await page.getSnackBarMessage()).toEqual(`There's already a folder with this name. Try a different name.`);
expect(await editDialog.isDialogOpen()).toBe(true, 'dialog is not present');
@ -225,9 +225,9 @@ describe('Edit folder', () => {
it('[C216338] trim ending spaces', async () => {
await dataTable.selectItem(folderName);
await toolbar.openMoreMenu();
await BrowserActions.click(toolbar.menu.editFolderAction);
await click(toolbar.menu.editFolderAction);
await editDialog.nameInput.sendKeys(' ');
await BrowserActions.click(editDialog.updateButton);
await click(editDialog.updateButton);
await editDialog.waitForDialogToClose();
expect(await page.snackBar.isPresent()).not.toBe(true, 'notification appears');

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, UserActions, LoginPage, BrowsingPage, RepoClient, Utils } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import { AdminActions, UserActions, LoginPage, BrowsingPage, RepoClient, Utils, click } from '@alfresco/aca-testing-shared';
describe('Download', () => {
const random = Utils.random();
@ -129,14 +128,14 @@ describe('Download', () => {
it('[C213179] Download a file', async () => {
await dataTable.selectItem(filePersonal);
await BrowserActions.click(toolbar.downloadButton);
await click(toolbar.downloadButton);
expect(await Utils.fileExistsOnOS(filePersonal)).toBe(true, 'File not found in download location');
});
it('[C216352] Download a folder', async () => {
await dataTable.selectItem(folderPersonal);
await BrowserActions.click(toolbar.downloadButton);
await click(toolbar.downloadButton);
const folderZip = `${folderPersonal}.zip`;
@ -149,7 +148,7 @@ describe('Download', () => {
it('[C216353] Download multiple items', async () => {
await dataTable.selectMultipleItems([filePersonal, folderPersonal]);
await BrowserActions.click(toolbar.downloadButton);
await click(toolbar.downloadButton);
expect(await Utils.fileExistsOnOS(archiveZip)).toBe(true, 'File not found in download location');

View File

@ -34,7 +34,6 @@ import {
UserActions
} from '@alfresco/aca-testing-shared';
import { browser } from 'protractor';
import { Logger } from '@alfresco/adf-testing';
describe('Version actions', () => {
const random = Utils.random();
@ -87,9 +86,7 @@ describe('Version actions', () => {
await loginPage.loginWith(username);
await dataTable.doubleClickOnRowByName(parentFolder);
await dataTable.waitForHeader();
} catch (error) {
Logger.error(`--- beforeAll failed : ${error}`);
}
} catch {}
});
afterAll(async () => {

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, UserActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import { AdminActions, UserActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils, click } from '@alfresco/aca-testing-shared';
describe('Comments', () => {
const username = `user1-${Utils.random()}`;
@ -113,7 +112,7 @@ describe('Comments', () => {
it('[C299173] Comments tab default fields', async () => {
await dataTable.selectItem(file1);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.clickCommentsTab();
@ -137,7 +136,7 @@ describe('Comments', () => {
const myComment = 'my comment';
await dataTable.selectItem(folder2);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.clickCommentsTab();
await commentsTab.typeComment(myComment);
@ -156,7 +155,7 @@ describe('Comments', () => {
it('[C299189] Comments are displayed ordered by created date in descending order', async () => {
await dataTable.selectItem(fileWith2Comments);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.clickCommentsTab();
@ -178,7 +177,7 @@ describe('Comments', () => {
const myComment = 'my comment';
await dataTable.selectItem(file2Recent);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.clickCommentsTab();
await commentsTab.typeComment(myComment);
@ -203,7 +202,7 @@ describe('Comments', () => {
await page.clickFavoritesAndWait();
await dataTable.selectItem(fileWith1Comment);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.clickCommentsTab();

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils, FILES } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import { AdminActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils, FILES, click, rightClick } from '@alfresco/aca-testing-shared';
describe('File / Folder properties', () => {
const username = `user1-${Utils.random()}`;
@ -87,7 +86,7 @@ describe('File / Folder properties', () => {
describe('View properties', () => {
it('[C299162] Default tabs', async () => {
await dataTable.selectItem(file1.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
expect(await infoDrawer.getHeaderTitle()).toEqual(file1.name);
@ -98,14 +97,14 @@ describe('File / Folder properties', () => {
it('[C599174] Should be able to make the files/folders info drawer expandable as for Sites', async () => {
await dataTable.selectItem(file1.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await infoDrawer.expandDetailsButton.click();
expect(await infoDrawer.expandedDetailsPermissionsTab.isPresent()).toBe(true, 'Permissions tab is not displayed');
await page.clickPersonalFilesAndWait();
await dataTable.selectItem(parent);
await BrowserActions.rightClick(dataTable.selectedRow);
await rightClick(dataTable.selectedRow);
await dataTable.menu.clickMenuItem('Permissions');
const expectedSelectedTabTitle = 'permissions';
const actualSelectedTabTitle = await infoDrawer.selectedTab.getText();

View File

@ -22,8 +22,19 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, LoginPage, BrowsingPage, RepoClient, FILES, SearchInput, DataTable, InfoDrawer } from '@alfresco/aca-testing-shared';
import { BrowserActions, ViewerPage } from '@alfresco/adf-testing';
import {
AdminActions,
LoginPage,
BrowsingPage,
RepoClient,
FILES,
SearchInput,
DataTable,
InfoDrawer,
click,
waitUntilElementIsVisible
} from '@alfresco/aca-testing-shared';
import { element, by, $$ } from 'protractor';
describe('File preview', () => {
const timestamp = new Date().getTime();
@ -41,7 +52,6 @@ describe('File preview', () => {
const dataTable = new DataTable();
const adminApiActions = new AdminActions();
const searchInput = new SearchInput();
const viewerPage = new ViewerPage();
beforeAll(async () => {
await adminApiActions.createUser({ username });
@ -58,13 +68,25 @@ describe('File preview', () => {
await browsingPage.clickPersonalFilesAndWait();
});
async function checkFileContent(pageNumber: string, text: string): Promise<void> {
const allPages = $$('.canvasWrapper > canvas').first();
const pageLoaded = $$('div[data-page-number="' + pageNumber + '"][data-loaded="true"]').first();
const textLayerLoaded = $$('div[data-page-number="' + pageNumber + '"] .textLayer').first();
const specificText = element.all(by.cssContainingText('div[data-page-number="' + pageNumber + '"] .textLayer', text)).first();
await waitUntilElementIsVisible(allPages);
await waitUntilElementIsVisible(pageLoaded);
await waitUntilElementIsVisible(textLayerLoaded);
await waitUntilElementIsVisible(specificText);
}
it('[C595967] Should preview document from the info drawer', async () => {
const pageNumber = '1';
const documentText = 'This is a small demonstration';
await searchInput.searchUntilResult(fileName, 'URL');
await dataTable.selectItem(fileName);
await BrowserActions.click(infoDrawer.toolbar.viewDetailsButton);
await click(infoDrawer.toolbar.viewDetailsButton);
await infoDrawer.previewButton.click();
await viewerPage.checkFileContent(pageNumber, documentText);
await checkFileContent(pageNumber, documentText);
});
});

View File

@ -22,8 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils, UserActions } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import { AdminActions, LoginPage, BrowsingPage, RepoClient, InfoDrawer, Utils, UserActions, click } from '@alfresco/aca-testing-shared';
describe('General', () => {
const username = `user1-${Utils.random()}`;
@ -69,13 +68,13 @@ describe('General', () => {
afterEach(async () => {
if (await infoDrawer.isOpen()) {
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
}
});
it('[C268999] Info drawer closes on page refresh', async () => {
await dataTable.selectItem(file1);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
expect(await infoDrawer.isOpen()).toBe(true, 'Info drawer not open');
await page.refresh();

View File

@ -22,8 +22,17 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AdminActions, LoginPage, BrowsingPage, SITE_VISIBILITY, SITE_ROLES, RepoClient, InfoDrawer, Utils } from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
import {
AdminActions,
LoginPage,
BrowsingPage,
SITE_VISIBILITY,
SITE_ROLES,
RepoClient,
InfoDrawer,
Utils,
click
} from '@alfresco/aca-testing-shared';
describe('Library properties', () => {
const username = `user1-${Utils.random()}`;
@ -90,13 +99,13 @@ describe('Library properties', () => {
afterEach(async () => {
if (await infoDrawer.isOpen()) {
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
}
});
it('[C289336] Info drawer opens for a library', async () => {
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
expect(await infoDrawer.getHeaderTitle()).toEqual(site.name);
@ -116,7 +125,7 @@ describe('Library properties', () => {
it('[C289338] Editable properties', async () => {
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled');
@ -135,7 +144,7 @@ describe('Library properties', () => {
it('[C289339] Edit site details', async () => {
await dataTable.selectItem(siteForUpdate.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled');
@ -162,7 +171,7 @@ describe('Library properties', () => {
const newDesc = `new desc ${Utils.random}`;
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
expect(await aboutTab.isEditLibraryPropertiesEnabled()).toBe(true, 'Edit action is not enabled');
@ -183,7 +192,7 @@ describe('Library properties', () => {
await apis.user.queries.waitForSites(site.name, { expect: 1 });
await dataTable.selectItem(siteDup);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await aboutTab.clickEditLibraryProperties();
@ -194,7 +203,7 @@ describe('Library properties', () => {
it('[C289342] Site name too long', async () => {
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await aboutTab.clickEditLibraryProperties();
@ -207,7 +216,7 @@ describe('Library properties', () => {
it('[C289343] Site description too long', async () => {
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await aboutTab.clickEditLibraryProperties();
@ -235,7 +244,7 @@ describe('Library properties', () => {
await page.goToMyLibrariesAndWait();
await dataTable.selectItem(site.name);
await BrowserActions.click(page.toolbar.viewDetailsButton);
await click(page.toolbar.viewDetailsButton);
await infoDrawer.waitForInfoDrawerToOpen();
await aboutTab.clickEditLibraryProperties();

View File

@ -31,9 +31,9 @@ import {
FILES,
SITE_VISIBILITY,
SITE_ROLES,
SizeOperator
SizeOperator,
click
} from '@alfresco/aca-testing-shared';
import { BrowserActions } from '@alfresco/adf-testing';
describe('Search filters', () => {
const random = Utils.random();
@ -160,7 +160,7 @@ describe('Search filters', () => {
describe('Filter by File type', () => {
afterEach(async () => {
await Utils.pressEscape();
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
});
it('[C279191] Expand / Collapse the File type filter panel', async () => {
@ -214,7 +214,7 @@ describe('Search filters', () => {
describe('Filter by People', () => {
afterEach(async () => {
await Utils.pressEscape();
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
});
it('[C279205] Expand / Collapse the People filter panel', async () => {
@ -241,7 +241,7 @@ describe('Search filters', () => {
expect(await dataTable.isItemPresent(fileJpgUser1.name)).toBe(true, 'JPG file not displayed');
expect(await peopleFilter.getChipTitle()).toEqual(`Created by: ${user1} ${user1} `);
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
await peopleFilter.openDialog();
await peopleFilter.selectChip(`${user2} ${user2}`);
await peopleFilter.clickApplyButton();
@ -261,7 +261,7 @@ describe('Search filters', () => {
expect(await dataTable.isItemPresent(fileJpgUser1.name)).toBe(true, 'JPG file not displayed');
expect(await peopleFilter.getChipTitle()).toEqual(`Modified by: ${user1} ${user1} `);
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
await peopleFilter.openDialog();
await peopleFilter.changeTabToModifier();
await peopleFilter.selectChip(`${user2} ${user2}`);
@ -311,7 +311,7 @@ describe('Search filters', () => {
describe('Filter by Location', () => {
afterEach(async () => {
await Utils.pressEscape();
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
});
it('[C279230] Expand / Collapse the Location filter panel', async () => {
@ -373,7 +373,7 @@ describe('Search filters', () => {
afterEach(async () => {
await Utils.pressEscape();
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
});
it('[C279219] Expand / Collapse the Modified date filter panel', async () => {
@ -439,7 +439,7 @@ describe('Search filters', () => {
describe('Multiple filters', () => {
afterEach(async () => {
await Utils.pressEscape();
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
});
it('[C280051] Multiple filters can be applied', async () => {
@ -463,7 +463,7 @@ describe('Search filters', () => {
expect(await peopleFilter.getChipTitle()).toEqual(`Created by: ${user1} ${user1} `);
expect(await locationFilter.getChipTitle()).toEqual(site);
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
expect(await dataTable.isItemPresent(filePdfUser2.name)).toBe(true, 'PDF file not displayed');
expect(await dataTable.isItemPresent(fileJpgUser1.name)).toBe(true, 'JPG file not displayed');
@ -480,7 +480,7 @@ describe('Search filters', () => {
expect(await dataTable.getRowsCount()).toEqual(1, 'expected 1 result');
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
expect(await dataTable.getRowsCount()).toEqual(2, 'expected 2 result');
});
@ -496,7 +496,7 @@ describe('Search filters', () => {
expect(await page.pagination.getRange()).toEqual('Showing 1-1 of 1');
await BrowserActions.click(filters.resetAllButton);
await click(filters.resetAllButton);
expect(await page.pagination.getRange()).toEqual('Showing 1-2 of 2');
});

View File

@ -23,7 +23,6 @@
*/
import { AdminActions, LoginPage, SearchResultsPage, RepoClient, Utils, SITE_VISIBILITY, SITE_ROLES } from '@alfresco/aca-testing-shared';
import { Logger } from '@alfresco/adf-testing';
describe('Search results - libraries', () => {
const random = Utils.random();
@ -116,18 +115,14 @@ describe('Search results - libraries', () => {
await apis.user.queries.waitForSites(random, { expect: 12 });
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
afterAll(async () => {
try {
await adminApiActions.sites.deleteSites([adminSite1, adminSite2, adminSite3, adminSite4, adminPrivate]);
await apis.user.sites.deleteSites([site1.id, site2.id, site3.id, site4.id, userSitePublic, userSiteModerated, userSitePrivate, siteRussian.id]);
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {

View File

@ -36,7 +36,6 @@ import {
UploadNewVersionDialog,
UploadFilesDialog
} from '@alfresco/aca-testing-shared';
import { Logger } from '@alfresco/adf-testing';
import { By, element } from 'protractor';
describe('Viewer actions', () => {
@ -108,9 +107,7 @@ describe('Viewer actions', () => {
await userActions.lockNodes([fileForCancelEditingId, fileForUploadNewVersionId, fileForUploadNewVersionId2]);
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {
@ -118,9 +115,7 @@ describe('Viewer actions', () => {
await page.clickPersonalFilesAndWait();
await dataTable.doubleClickOnRowByName(parent);
await dataTable.waitForHeader();
} catch (error) {
Logger.error(`----- beforeEach failed : ${error}`);
}
} catch {}
});
afterEach(async () => {
@ -133,9 +128,7 @@ describe('Viewer actions', () => {
await userActions.login(username, username);
await userActions.deleteNodes([parentId, destinationId]);
await userActions.emptyTrashcan();
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
it('[C297585] Cancel Editing action', async () => {
@ -220,9 +213,7 @@ describe('Viewer actions', () => {
await apis.user.search.waitForApi(username, { expect: 7 });
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {
@ -239,9 +230,7 @@ describe('Viewer actions', () => {
await userActions.login(username, username);
await userActions.deleteNodes([parentId, destinationId]);
await userActions.emptyTrashcan();
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
it('[C286384] Copy action', async () => {
@ -322,9 +311,7 @@ describe('Viewer actions', () => {
]);
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {
@ -336,9 +323,7 @@ describe('Viewer actions', () => {
await page.closeOpenDialogs();
await Utils.pressEscape();
await uploadFilesDialog.closeUploadDialog();
} catch (error) {
Logger.error(`----- afterEach failed : ${error}`);
}
} catch {}
});
afterAll(async () => {
@ -346,9 +331,7 @@ describe('Viewer actions', () => {
await userActions.login(username, username);
await userActions.deleteNodes([parentId, destinationId]);
await userActions.emptyTrashcan();
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
it('[C286379] Favorite action', async () => {
@ -404,9 +387,7 @@ describe('Viewer actions', () => {
await apis.user.favorites.waitForApi({ expect: 7 });
await loginPage.loginWith(username);
} catch (error) {
Logger.error(`----- beforeAll failed : ${error}`);
}
} catch {}
});
beforeEach(async () => {
@ -423,9 +404,7 @@ describe('Viewer actions', () => {
await userActions.login(username, username);
await userActions.deleteNodes([parentId, destinationId]);
await userActions.emptyTrashcan();
} catch (error) {
Logger.error(`----- afterAll failed : ${error}`);
}
} catch {}
});
it('[C286395] Share action', async () => {

21
package-lock.json generated
View File

@ -43,7 +43,6 @@
},
"devDependencies": {
"@alfresco/adf-cli": "6.6.0-7447507400",
"@alfresco/adf-testing": "6.6.0-7447507400",
"@angular-devkit/build-angular": "14.2.11",
"@angular-devkit/core": "14.1.2",
"@angular-devkit/schematics": "14.1.2",
@ -205,26 +204,6 @@
"@angular/core": ">=14.1.3"
}
},
"node_modules/@alfresco/adf-testing": {
"version": "6.6.0-7447507400",
"resolved": "https://registry.npmjs.org/@alfresco/adf-testing/-/adf-testing-6.6.0-7447507400.tgz",
"integrity": "sha512-QifuLcuOX+/kuvc81wCYiMeP10yIs3ktWOuZHfFkIkAIu25BG7JRHXLOjTsPpjAXU0DxlctDTHK9EGshNq/gAw==",
"dev": true,
"dependencies": {
"@alfresco/js-api": ">=7.5.0-7447507400",
"@angular/compiler": "14.1.3",
"@angular/core": "14.1.3",
"date-fns": "^2.30.0",
"event-emitter": "^0.3.5",
"rxjs": "6.6.6",
"superagent": "^8.1.2",
"tslib": "^2.6.2",
"zone.js": "~0.11.4"
},
"peerDependencies": {
"@alfresco/js-api": ">=7.5.0-7447507400"
}
},
"node_modules/@alfresco/eslint-plugin-eslint-angular": {
"version": "6.6.0-7447507400",
"resolved": "https://registry.npmjs.org/@alfresco/eslint-plugin-eslint-angular/-/eslint-plugin-eslint-angular-6.6.0-7447507400.tgz",

View File

@ -66,7 +66,6 @@
},
"devDependencies": {
"@alfresco/adf-cli": "6.6.0-7447507400",
"@alfresco/adf-testing": "6.6.0-7447507400",
"@angular-devkit/build-angular": "14.2.11",
"@angular-devkit/core": "14.1.2",
"@angular-devkit/schematics": "14.1.2",

View File

@ -24,7 +24,6 @@
import { ApiClientFactory } from './api-client-factory';
import { FavoriteEntry, FavoritePaging } from '@alfresco/js-api';
import { Logger } from '@alfresco/adf-testing';
import { Utils } from '../utils';
export class FavoritesPageApi {
@ -59,26 +58,22 @@ export class FavoritesPageApi {
favorites.push(favorite);
}
}
} catch (error) {
Logger.error(`FavoritesApi addFavoritesByIds : catch : `, error);
}
} catch {}
return favorites;
}
private async getFavorites(username: string): Promise<FavoritePaging> {
try {
return await this.apiService.favorites.listFavorites(username);
} catch (error) {
Logger.error(`FavoritesApi getFavorites : catch : `, error);
return new FavoritePaging;
} catch {
return new FavoritePaging();
}
}
async isFavorite(username: string, nodeId: string): Promise<boolean> {
try {
return JSON.stringify((await this.getFavorites(username)).list.entries).includes(nodeId);
} catch (error) {
Logger.error(`FavoritesApi isFavorite : catch : `, error);
} catch {
return false;
}
}
@ -102,8 +97,7 @@ export class FavoritesPageApi {
async getFavoritesTotalItems(username: string): Promise<number> {
try {
return (await this.apiService.favorites.listFavorites(username)).list.pagination.totalItems;
} catch (error) {
Logger.error(`FavoritesApi getFavoritesTotalItems : catch : `, error);
} catch {
return -1;
}
}
@ -119,9 +113,6 @@ export class FavoritesPageApi {
}
};
return await Utils.retryCall(favoriteFiles);
} catch (error) {
Logger.error(`FavoritesApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
} catch {}
}
}

View File

@ -25,8 +25,8 @@
import * as fs from 'fs';
import { ApiClientFactory } from './api-client-factory';
import { Utils } from '../utils';
import { ApiUtil, Logger } from '@alfresco/adf-testing';
import { NodeBodyCreate, NodeEntry, ResultSetPaging } from '@alfresco/js-api';
import { waitForApi } from '@alfresco/aca-testing-shared';
export class FileActionsApi {
private apiService: ApiClientFactory;
@ -73,7 +73,6 @@ export class FileActionsApi {
try {
return await this.apiService.upload.uploadFile(file, '', parentId, nodeProps, opts);
} catch (error) {
Logger.error(`${this.constructor.name} ${this.uploadFileWithRename.name}`, error);
return Promise.reject(error);
}
}
@ -83,16 +82,13 @@ export class FileActionsApi {
for (const nodeId of nodeIds) {
await this.apiService.nodes.lockNode(nodeId, { type: lockType });
}
} catch (error) {
Logger.error(`${this.constructor.name} ${this.lockNodes.name}`, error);
}
} catch {}
}
async getNodeById(id: string): Promise<NodeEntry | null> {
try {
return await this.apiService.nodes.getNode(id);
} catch (error) {
Logger.error(`${this.constructor.name} ${this.getNodeById.name}`, error);
} catch {
return null;
}
}
@ -101,8 +97,7 @@ export class FileActionsApi {
try {
const node = await this.getNodeById(nodeId);
return node.entry.properties?.[property] || '';
} catch (error) {
Logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error);
} catch {
return '';
}
}
@ -111,8 +106,7 @@ export class FileActionsApi {
try {
const lockType = await this.getNodeProperty(nodeId, 'cm:lockType');
return lockType || '';
} catch (error) {
Logger.error(`${this.constructor.name} ${this.getLockType.name}`, error);
} catch {
return '';
}
}
@ -133,9 +127,7 @@ export class FileActionsApi {
}
};
return await Utils.retryCall(locked, data.retry);
} catch (error) {
Logger.error(`${this.constructor.name} ${this.isFileLockedWriteWithRetry.name}`, error);
}
} catch {}
return isLocked;
}
@ -150,8 +142,7 @@ export class FileActionsApi {
try {
return await this.apiService.search.search(data);
} catch (error) {
Logger.error(`SearchApi queryNodesNames : catch : `, error);
} catch {
return new ResultSetPaging();
}
}
@ -168,11 +159,8 @@ export class FileActionsApi {
};
try {
await ApiUtil.waitForApi(apiCall, predicate, 30, 2500);
} catch (error) {
Logger.error(`SearchApi waitForNodes : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
await waitForApi(apiCall, predicate, 30, 2500);
} catch {}
}
async updateNodeContent(nodeId: string, content: string, majorVersion: boolean = true, comment?: string, newName?: string): Promise<NodeEntry> {

View File

@ -23,7 +23,6 @@
*/
import { ApiClientFactory } from './api-client-factory';
import { Logger } from '@alfresco/adf-testing';
import { Utils } from '../utils';
import { ResultSetPaging } from '@alfresco/js-api';
@ -54,14 +53,13 @@ export class SearchPageApi {
try {
return await this.apiService.search.search(data);
} catch (error) {
Logger.error(`SearchApi queryRecentFiles : catch : `, error);
return new ResultSetPaging;
} catch {
return new ResultSetPaging();
}
}
async getTotalItems(username: string): Promise<number> {
return (await this.querySearchFiles(username)).list.pagination.totalItems;
return (await this.querySearchFiles(username)).list.pagination.totalItems;
}
async waitForApi(username: string, data: { expect: number }) {
@ -76,9 +74,6 @@ export class SearchPageApi {
};
return await Utils.retryCall(searchFiles);
} catch (error) {
Logger.error(`SearchApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
} catch {}
}
}

View File

@ -22,13 +22,22 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { StringUtil } from '@alfresco/adf-testing';
const LOWER_CASE_ALPHA = 'helloworld';
function generateRandomCharset(length: number = 8, charSet: string): string {
let text = '';
for (let i = 0; i < length; i++) {
text += charSet.charAt(Math.floor(Math.random() * charSet.length));
}
return text;
}
export class UserModel {
firstName?: string = StringUtil.generateRandomCharset(length, LOWER_CASE_ALPHA)(7);
lastName?: string = StringUtil.generateRandomCharset(length, LOWER_CASE_ALPHA)(7);
password?: string = StringUtil.generateRandomCharset(length, LOWER_CASE_ALPHA)(7);
firstName?: string = generateRandomCharset(7, LOWER_CASE_ALPHA);
lastName?: string = generateRandomCharset(7, LOWER_CASE_ALPHA);
password?: string = generateRandomCharset(7, LOWER_CASE_ALPHA);
email?: string;
username?: string;
idIdentityService?: string;
@ -42,7 +51,7 @@ export class UserModel {
this.firstName = details.firstName ?? this.firstName;
this.lastName = details.lastName ?? this.lastName;
const USER_IDENTIFY = `${this.firstName}${this.lastName}.${StringUtil.generateRandomCharset(length, LOWER_CASE_ALPHA)(7)}`;
const USER_IDENTIFY = `${this.firstName}${this.lastName}.${generateRandomCharset(7, LOWER_CASE_ALPHA)}`;
this.password = details.password ?? this.password;
this.email = details.email ?? `${USER_IDENTIFY}@${EMAIL_DOMAIN}.com`;

View File

@ -64,9 +64,6 @@ export class LoginPage extends BasePage {
async isPasswordDisplayed(): Promise<boolean> {
const type = await this.password.getAttribute('type');
if (type === 'text') {
return true;
}
return false;
return type === 'text';
}
}

View File

@ -22,8 +22,8 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { GenericLogger, LoggerLike } from '@alfresco/adf-testing';
import { Page } from '@playwright/test';
import { GenericLogger, LoggerLike } from '@alfresco/aca-testing-shared';
export abstract class PlaywrightBase {
public page: Page;

View File

@ -23,10 +23,9 @@
*/
import { browser, by, ElementArrayFinder, ElementFinder } from 'protractor';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { Menu } from '../menu/menu';
import { Utils, waitForPresence } from '../../utilities';
import { Utils, waitForPresence, waitUntilElementIsClickable } from '../../utilities';
export class DataTable extends Component {
private static selectors = {
@ -108,7 +107,6 @@ export class DataTable extends Component {
}
async hasCheckMarkIcon(itemName: string, location: string = ''): Promise<boolean> {
Logger.info(`--- check if item already selected : ${itemName} ${location}`);
const row = this.getRowByName(itemName, location);
return row.element(by.css('.mat-icon[class*="selected"]')).isPresent();
}
@ -134,11 +132,11 @@ export class DataTable extends Component {
async doubleClickOnRowByName(name: string, location: string = ''): Promise<void> {
try {
const item = this.getRowFirstCell(name, location);
await BrowserVisibility.waitUntilElementIsClickable(item);
await waitUntilElementIsClickable(item);
await browser.actions().mouseMove(item).perform();
await browser.actions().doubleClick().perform();
} catch (error) {
Logger.error(`--- doubleClickOnRowByName catch : failed to double click on ${name} from location : ${location} : `, error);
console.error(`--- doubleClickOnRowByName catch : failed to double click on ${name} from location : ${location} : `, error);
}
}
@ -146,11 +144,10 @@ export class DataTable extends Component {
const isSelected = await this.hasCheckMarkIcon(name, location);
if (!isSelected) {
try {
Logger.info(`--- selecting item : ${name} ${location}`);
const item = this.getRowFirstCell(name, location);
await item.click();
} catch (e) {
Logger.error(`--- select item catch : failed to select ${name} from location : ${location} : `, e);
console.error(`--- select item catch : failed to select ${name} from location : ${location} : `, e);
}
}
}
@ -162,7 +159,7 @@ export class DataTable extends Component {
const item = this.getRowFirstCell(name, location);
await item.click();
} catch (e) {
Logger.error(`--- unselect item catch : failed to unselect ${name} from location : ${location} : `, e);
console.error(`--- unselect item catch : failed to unselect ${name} from location : ${location} : `, e);
}
}
}
@ -184,7 +181,7 @@ export class DataTable extends Component {
await this.wait();
}
} catch (error) {
Logger.error('------ clearSelection catch : ', error);
console.error('------ clearSelection catch : ', error);
}
}

View File

@ -24,9 +24,8 @@
import { by, browser } from 'protractor';
import { GenericDialog } from './generic-dialog';
import { waitForStaleness, waitForPresence } from '../../utilities';
import { waitForStaleness, waitForPresence, click } from '../../utilities';
import { DataTable } from '../data-table/data-table';
import { BrowserActions } from '@alfresco/adf-testing';
export class ContentNodeSelectorDialog extends GenericDialog {
copyButton = this.childElement(by.cssContainingText('[data-automation-id="content-node-selector-actions-choose"]', 'Copy'));
@ -52,12 +51,12 @@ export class ContentNodeSelectorDialog extends GenericDialog {
}
async selectLocation(location: string): Promise<void> {
await BrowserActions.click(this.locationDropDown);
await click(this.locationDropDown);
if (location === 'Personal Files') {
await BrowserActions.click(this.locationPersonalFiles);
await click(this.locationPersonalFiles);
} else {
await BrowserActions.click(this.locationFileLibraries);
await click(this.locationFileLibraries);
}
await this.waitForDropDownToClose();
@ -65,7 +64,7 @@ export class ContentNodeSelectorDialog extends GenericDialog {
async selectDestination(folderName: string): Promise<void> {
const row = this.dataTable.getRowByName(folderName);
await BrowserActions.click(row);
await click(row);
await waitForPresence(browser.element(by.css('.adf-is-selected')));
}
}

View File

@ -24,8 +24,7 @@
import { by } from 'protractor';
import { GenericDialog } from './generic-dialog';
import { isPresentAndDisplayed, isPresentAndEnabled, typeText } from '../../utilities';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
import { click, getInputValue, isPresentAndDisplayed, isPresentAndEnabled, typeText, waitUntilElementIsClickable } from '../../utilities';
export class CreateOrEditFolderDialog extends GenericDialog {
createButton = this.childElement(by.cssContainingText('.mat-dialog-actions button', 'Create'));
@ -42,7 +41,7 @@ export class CreateOrEditFolderDialog extends GenericDialog {
async waitForDialogToOpen() {
await super.waitForDialogToOpen();
await BrowserVisibility.waitUntilElementIsClickable(this.nameInput);
await waitUntilElementIsClickable(this.nameInput);
}
async isUpdateButtonEnabled(): Promise<boolean> {
@ -62,11 +61,11 @@ export class CreateOrEditFolderDialog extends GenericDialog {
}
async getName(): Promise<string> {
return BrowserActions.getInputValue(this.nameInput);
return getInputValue(this.nameInput);
}
async getDescription(): Promise<string> {
return BrowserActions.getInputValue(this.descriptionTextArea);
return getInputValue(this.descriptionTextArea);
}
async enterName(name: string): Promise<void> {
@ -78,7 +77,7 @@ export class CreateOrEditFolderDialog extends GenericDialog {
}
async clickCancel(): Promise<void> {
await BrowserActions.click(this.cancelButton);
await click(this.cancelButton);
await this.waitForDialogToClose();
}
}

View File

@ -23,8 +23,7 @@
*/
import { ElementFinder, by, browser, Locator } from 'protractor';
import { isPresentAndDisplayed, waitForPresence, waitForStaleness } from '../../utilities/utils';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { isPresentAndDisplayed, waitForPresence, waitForStaleness, waitUntilElementIsVisible } from '../../utilities';
export abstract class GenericDialog {
protected constructor(private rootCssSelector?: string) {}
@ -47,16 +46,14 @@ export abstract class GenericDialog {
async waitForDialogToOpen(): Promise<void> {
await waitForPresence(this.rootElem);
await BrowserVisibility.waitUntilElementIsVisible(this.content);
await waitUntilElementIsVisible(this.content);
await waitForPresence(browser.element(by.css('.cdk-overlay-backdrop')));
}
async waitForDialogToClose(): Promise<void> {
try {
await waitForStaleness(this.content);
} catch (error) {
Logger.error(`GenericDialog waitForDialogToClose : catch : ${error}`);
}
} catch {}
}
async isDialogOpen(): Promise<boolean> {

View File

@ -24,8 +24,8 @@
import { by } from 'protractor';
import { GenericDialog } from './generic-dialog';
import { BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { click } from '../../utilities';
export class ManageVersionsDialog extends GenericDialog {
menu = new Menu();
@ -35,7 +35,7 @@ export class ManageVersionsDialog extends GenericDialog {
}
async clickActionButton(version: string): Promise<void> {
await BrowserActions.click(this.childElement(by.id(`adf-version-list-action-menu-button-${version}`)));
await click(this.childElement(by.id(`adf-version-list-action-menu-button-${version}`)));
await this.menu.waitForMenuToOpen();
}

View File

@ -22,7 +22,7 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { TestElement } from '@alfresco/adf-testing';
import { TestElement } from '../../utilities';
export class UploadFilesDialog {
uploadDialog = TestElement.byCss('.adf-upload-dialog');

View File

@ -27,8 +27,7 @@ import { Component } from '../component';
import { Menu } from '../menu/menu';
import { Toolbar } from '../toolbar/toolbar';
import { SearchInput } from '../search';
import { waitElement } from '../../utilities';
import { BrowserActions } from '@alfresco/adf-testing';
import { click, waitElement } from '../../utilities';
export class Header extends Component {
userMenuButton = this.byCss(`.aca-user-menu-button`);
@ -43,7 +42,7 @@ export class Header extends Component {
}
async openMoreMenu(): Promise<void> {
await BrowserActions.click(this.userMenuButton);
await click(this.userMenuButton);
await this.menu.waitForMenuToOpen();
}
@ -54,7 +53,7 @@ export class Header extends Component {
async expandSideNav(): Promise<void> {
const expanded = await this.isSidenavExpanded();
if (!expanded) {
await BrowserActions.click(this.sidenavToggle);
await click(this.sidenavToggle);
await waitElement(`[data-automation-id='expanded']`);
}
}

View File

@ -25,8 +25,7 @@
import { by, browser, until } from 'protractor';
import { Component } from '../component';
import { BROWSER_WAIT_TIMEOUT } from '../../configs';
import { typeText } from '../../utilities';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
import { click, typeText, waitUntilElementIsVisible } from '../../utilities';
export class CommentsTab extends Component {
commentsContainer = this.byCss('.adf-comments-container');
@ -44,7 +43,7 @@ export class CommentsTab extends Component {
}
async waitForCommentsContainer() {
await BrowserVisibility.waitUntilElementIsVisible(this.commentsContainer);
await waitUntilElementIsVisible(this.commentsContainer);
}
async getCommentsTabHeaderText(): Promise<string> {
@ -111,6 +110,6 @@ export class CommentsTab extends Component {
}
async clickAddButton(): Promise<void> {
await BrowserActions.click(this.addCommentButton);
await click(this.addCommentButton);
}
}

View File

@ -23,9 +23,8 @@
*/
import { by, browser } from 'protractor';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { Component } from '../component';
import { waitForPresence, waitForStaleness, typeText } from '../../utilities';
import { waitForPresence, waitForStaleness, typeText, click } from '../../utilities';
export class LibraryMetadata extends Component {
visibilityDropDown = this.component.element(by.css('.mat-select'));
@ -80,7 +79,7 @@ export class LibraryMetadata extends Component {
}
private async clickButton(button: string) {
await BrowserActions.click(this.getButton(button));
await click(this.getButton(button));
}
async waitForVisibilityDropDownToClose() {
@ -152,17 +151,17 @@ export class LibraryMetadata extends Component {
async setVisibility(visibility: string) {
const val = visibility.toLowerCase();
await BrowserActions.click(this.visibilityDropDown);
await click(this.visibilityDropDown);
await waitForPresence(this.visibilityDropDown);
if (val === 'public') {
await BrowserActions.click(this.visibilityPublic);
await click(this.visibilityPublic);
} else if (val === 'private') {
await BrowserActions.click(this.visibilityPrivate);
await click(this.visibilityPrivate);
} else if (val === 'moderated') {
await BrowserActions.click(this.visibilityModerated);
await click(this.visibilityModerated);
} else {
Logger.error('----- invalid visibility', val);
console.error('----- invalid visibility', val);
}
await this.waitForVisibilityDropDownToClose();

View File

@ -23,11 +23,10 @@
*/
import { browser } from 'protractor';
import { BrowserActions, BrowserVisibility, Logger, TestElement } from '@alfresco/adf-testing';
import { Component } from '../component';
import { CommentsTab } from './info-drawer-comments-tab';
import { LibraryMetadata } from './info-drawer-metadata-library';
import { waitForPresence } from '../../utilities';
import { click, TestElement, waitForPresence, waitUntilElementIsVisible } from '../../utilities';
import { Toolbar } from '../toolbar/toolbar';
export class InfoDrawer extends Component {
@ -88,11 +87,11 @@ export class InfoDrawer extends Component {
async clickCommentsTab() {
try {
await BrowserActions.click(this.getTabByTitle('Comments'));
await click(this.getTabByTitle('Comments'));
await this.commentsTab.waitForCommentsContainer();
await Promise.all([BrowserVisibility.waitUntilElementIsVisible(this.commentsTab.component)]);
await waitUntilElementIsVisible(this.commentsTab.component);
} catch (error) {
Logger.error('--- info-drawer clickCommentsTab catch error: ', error);
console.error('--- info-drawer clickCommentsTab catch error: ', error);
}
}
}

View File

@ -23,9 +23,8 @@
*/
import { ElementFinder, by, browser } from 'protractor';
import { Logger, BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
import { Component } from '../component';
import { waitForPresence, waitForStaleness } from '../../utilities';
import { click, waitForPresence, waitForStaleness, waitUntilElementIsVisible } from '../../utilities';
export class Menu extends Component {
items = this.allByCss('.mat-menu-item');
@ -41,17 +40,13 @@ export class Menu extends Component {
async waitForMenuToOpen(): Promise<void> {
await waitForPresence(browser.element(by.css('.cdk-overlay-container .mat-menu-panel')));
await BrowserVisibility.waitUntilElementIsVisible(this.items.get(0));
await waitUntilElementIsVisible(this.items.get(0));
}
async waitForMenuToClose(): Promise<void> {
await waitForStaleness(browser.element(by.css('.cdk-overlay-container .mat-menu-panel')));
}
getNthItem(nth: number): ElementFinder {
return this.items.get(nth - 1);
}
private getItemByLabel(menuItem: string): ElementFinder {
return this.byCssText('.mat-menu-item', menuItem);
}
@ -60,24 +55,12 @@ export class Menu extends Component {
return this.getItemByLabel(menuItem).element(by.css('.mat-icon')).getText();
}
async clickNthItem(nth: number): Promise<void> {
try {
const elem = this.getNthItem(nth);
await BrowserVisibility.waitUntilElementIsClickable(elem);
await browser.actions().mouseMove(elem).perform();
await browser.actions().click().perform();
await this.waitForMenuToClose();
} catch (e) {
Logger.error('____ click nth menu item catch ___', e);
}
}
async clickMenuItem(menuItem: string): Promise<void> {
try {
const elem = this.getItemByLabel(menuItem);
await BrowserActions.click(elem);
await click(elem);
} catch (e) {
Logger.error(`___click menu item catch : failed to click on ${menuItem}___`, e);
console.error(`___click menu item catch : failed to click on ${menuItem}___`, e);
}
}
}

View File

@ -23,8 +23,8 @@
*/
import { ElementFinder, ElementArrayFinder, by, browser, protractor, element } from 'protractor';
import { BrowserVisibility } from '@alfresco/adf-testing';
import { GenericFilter } from './generic-filter';
import { waitUntilElementHasText } from '../../../utilities';
export class FacetTabbedFilter extends GenericFilter {
private readonly locators = {
@ -61,12 +61,12 @@ export class FacetTabbedFilter extends GenericFilter {
async changeTabToModifier(): Promise<void> {
await this.tabs.get(1).click();
await BrowserVisibility.waitUntilElementHasText(await this.filterDialogOpened.element(by.css(this.locators.currentTabLabel)), 'Modifier');
await waitUntilElementHasText(await this.filterDialogOpened.element(by.css(this.locators.currentTabLabel)), 'Modifier');
}
async changeTabToCreator(): Promise<void> {
await this.tabs.get(0).click();
await BrowserVisibility.waitUntilElementHasText(await this.filterDialogOpened.element(by.css(this.locators.currentTabLabel)), 'Creator');
await waitUntilElementHasText(await this.filterDialogOpened.element(by.css(this.locators.currentTabLabel)), 'Creator');
}
async isChipListDisplayed(): Promise<boolean> {

View File

@ -22,9 +22,18 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { ElementFinder, by, browser } from 'protractor';
import { isPresentAndDisplayed, Utils } from '../../../utilities/utils';
import { BrowserActions, TestElement } from '@alfresco/adf-testing';
import { ElementFinder, by, browser, element } from 'protractor';
import { isPresentAndDisplayed, Utils, waitUntilElementIsVisible, waitUntilElementIsNotVisible, TestElement } from '../../../utilities';
async function waitUntilActionMenuIsVisible(): Promise<void> {
const actionMenu = element.all(by.css('div[role="menu"]')).first();
await waitUntilElementIsVisible(actionMenu);
}
async function waitUntilActionMenuIsNotVisible(): Promise<void> {
const actionMenu = element.all(by.css('div[role="menu"]')).first();
await waitUntilElementIsNotVisible(actionMenu);
}
export class GenericFilter {
private readonly filterName: string;
@ -70,14 +79,14 @@ export class GenericFilter {
async openDialog(): Promise<void> {
if (!(await this.isDialogPresent())) {
await this.chip.click();
await BrowserActions.waitUntilActionMenuIsVisible();
await waitUntilActionMenuIsVisible();
}
}
async closeDialog(): Promise<void> {
if (await this.isDialogPresent()) {
await Utils.pressEscape();
await BrowserActions.waitUntilActionMenuIsNotVisible();
await waitUntilActionMenuIsNotVisible();
}
}
}

View File

@ -24,8 +24,7 @@
import { browser, by } from 'protractor';
import { Component } from '../component';
import { waitElement, waitForPresence } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility, TestElement } from '@alfresco/adf-testing';
import { click, waitElement, waitForPresence, waitUntilElementIsClickable, getUrl, TestElement } from '../../utilities';
export class SearchInput extends Component {
get searchButton() {
@ -58,7 +57,7 @@ export class SearchInput extends Component {
}
async clickSearchButton() {
await BrowserActions.click(this.searchButton);
await click(this.searchButton);
await this.waitForSearchControl();
}
@ -69,15 +68,15 @@ export class SearchInput extends Component {
}
async clickFilesOption() {
await BrowserActions.click(this.searchFilesOption);
await click(this.searchFilesOption);
}
async clickFoldersOption() {
await BrowserActions.click(this.searchFoldersOption);
await click(this.searchFoldersOption);
}
async clickLibrariesOption() {
await BrowserActions.click(this.searchLibrariesOption);
await click(this.searchLibrariesOption);
}
async isFilesOptionEnabled() {
@ -143,19 +142,19 @@ export class SearchInput extends Component {
}
async searchForLibrary(text: string) {
await BrowserVisibility.waitUntilElementIsClickable(this.searchInput.elementFinder);
await waitUntilElementIsClickable(this.searchInput.elementFinder);
await this.searchInput.typeText(text);
}
async searchFor(text: string) {
await BrowserVisibility.waitUntilElementIsClickable(this.searchInput.elementFinder);
await waitUntilElementIsClickable(this.searchInput.elementFinder);
await this.searchInput.typeText(text);
await BrowserActions.click(this.searchButton);
await click(this.searchButton);
}
async searchByURL(text: string) {
const query = Buffer.from(text, 'utf-8').toString();
await BrowserActions.getUrl(`#/search;q=${query}`);
await getUrl(`#/search;q=${query}`);
}
async searchUntilResult(text: string, methodType: 'URL' | 'UI', waitPerSearch: number = 2000, timeout: number = 20000) {

View File

@ -24,8 +24,7 @@
import { by, browser } from 'protractor';
import { Component } from '../component';
import { isPresentAndDisplayed } from '../../utilities/utils';
import { BrowserActions, BrowserVisibility } from '@alfresco/adf-testing';
import { isPresentAndDisplayed, waitUntilElementIsVisible, click } from '../../utilities';
export type SortByType = 'Relevance' | 'Title' | 'Filename' | 'Modified date' | 'Modifier' | 'Created date' | 'Size' | 'Type';
export class SearchSortingPicker extends Component {
@ -39,11 +38,7 @@ export class SearchSortingPicker extends Component {
}
async waitForSortByDropdownToExpand(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(
this.sortByDropdownExpanded,
BrowserVisibility.DEFAULT_TIMEOUT,
'Timeout waiting for sortBy dropdown to expand'
);
await waitUntilElementIsVisible(this.sortByDropdownExpanded);
}
async isSortOrderButtonDisplayed(): Promise<boolean> {
@ -54,8 +49,8 @@ export class SearchSortingPicker extends Component {
}
async clickSortByDropdown(): Promise<void> {
await BrowserActions.click(this.actionMenu);
await BrowserActions.click(this.sortOrderButton);
await click(this.actionMenu);
await click(this.sortOrderButton);
await this.waitForSortByDropdownToExpand();
}
@ -71,8 +66,8 @@ export class SearchSortingPicker extends Component {
}
const elem = browser.element(by.cssContainingText('.mat-menu-item', option));
const optionId = await elem.getAttribute('id');
await BrowserActions.click(elem);
await click(elem);
const directionSortElement = browser.element(by.id(`${optionId}-${direction.toLocaleLowerCase()}`));
await BrowserActions.click(directionSortElement);
await click(directionSortElement);
}
}

View File

@ -23,9 +23,9 @@
*/
import { ElementFinder, by, browser } from 'protractor';
import { Logger, BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { click } from '../../utilities';
export class Sidenav extends Component {
links = this.component.all(by.css('.item'));
@ -75,9 +75,9 @@ export class Sidenav extends Component {
async clickLink(name: string): Promise<void> {
try {
const link = this.getLinkLabel(name);
await BrowserActions.click(link);
await click(link);
} catch (error) {
Logger.error(`---- clickLink catch : sidebar navigation failed to click on - ${name} : `, error);
console.error(`---- clickLink catch : sidebar navigation failed to click on - ${name} : `, error);
}
}
}

View File

@ -23,10 +23,9 @@
*/
import { by, browser, By, element } from 'protractor';
import { BrowserActions } from '@alfresco/adf-testing';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { Utils } from '../../utilities';
import { click, Utils } from '../../utilities';
export class Toolbar extends Component {
menu = new Menu();
@ -51,13 +50,13 @@ export class Toolbar extends Component {
}
async clickSearchIconButton() {
await BrowserActions.click(this.searchIconButton);
await click(this.searchIconButton);
}
async openMoreMenu(): Promise<void> {
const btnMoreActions = element(By.css('button[id="app.toolbar.more"]'));
await btnMoreActions.isPresent();
await BrowserActions.click(btnMoreActions);
await click(btnMoreActions);
await this.menu.waitForMenuToOpen();
await browser.sleep(500);
@ -68,12 +67,12 @@ export class Toolbar extends Component {
}
async openUploadMenu(): Promise<void> {
await BrowserActions.click(this.uploadButton);
await click(this.uploadButton);
await this.menu.waitForMenuToOpen();
}
async closeUploadMenu(): Promise<void> {
await BrowserActions.click(element(by.css('button[id="app.toolbar.upload"]')));
await click(element(by.css('button[id="app.toolbar.upload"]')));
await this.menu.waitForMenuToClose();
}

View File

@ -26,8 +26,7 @@ import { browser } from 'protractor';
import { LoginComponent } from '../components';
import { Page } from './page';
import { APP_ROUTES } from '../configs';
import { waitForPresence } from '../utilities';
import { BrowserActions, Logger } from '@alfresco/adf-testing';
import { click, waitForPresence } from '../utilities';
export class LoginPage extends Page {
login = new LoginComponent(this.appRoot);
@ -53,10 +52,10 @@ export class LoginPage extends Page {
await this.load();
await this.login.enterCredentials(username, pass);
await BrowserActions.click(this.login.submitButton);
await click(this.login.submitButton);
await this.waitForApp();
} catch (error) {
Logger.error(`----- loginWith catch : failed to login with user: ${username} : ${error}`);
console.error(`----- loginWith catch : failed to login with user: ${username} : ${error}`);
}
}

View File

@ -23,9 +23,8 @@
*/
import { browser, by, ElementFinder, WebElement } from 'protractor';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { APP_ROUTES, USE_HASH_STRATEGY } from './../configs';
import { Utils, waitElement, waitForPresence, isPresentAndDisplayed } from '../utilities/utils';
import { APP_ROUTES, USE_HASH_STRATEGY } from '../configs';
import { Utils, waitElement, waitForPresence, isPresentAndDisplayed, waitUntilElementIsPresent, waitUntilElementIsVisible } from '../utilities';
import { Header } from '../components';
import { UploadFilesDialog } from '../components/dialog/upload-files-dialog';
@ -59,11 +58,11 @@ export abstract class Page {
const header = new Header();
await header.openMoreMenu();
await header.menu.clickMenuItem('Sign out');
await BrowserVisibility.waitUntilElementIsPresent(browser.element(by.css('[class*="login-content"] input#username')));
await waitUntilElementIsPresent(browser.element(by.css('[class*="login-content"] input#username')));
}
async waitForDialog(): Promise<void> {
await BrowserVisibility.waitUntilElementIsVisible(this.dialogContainer);
await waitUntilElementIsVisible(this.dialogContainer);
}
async isDialogOpen(): Promise<boolean> {
@ -103,7 +102,7 @@ export abstract class Page {
const action = await waitElement(`[data-automation-id='adf-snackbar-message-content-action-button']`);
await action.click();
} catch (e) {
Logger.error(e, '.......failed on click snack bar action.........');
console.error(e, '.......failed on click snack bar action.........');
}
}

View File

@ -0,0 +1,46 @@
/*!
* Copyright © 2005-2023 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
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
export type ApiResultPredicate<T> = (result: T) => boolean;
export type ApiCall<T> = () => Promise<T>;
export async function waitForApi<T>(apiCall: ApiCall<T>, predicate: ApiResultPredicate<T>, retry: number = 30, delay: number = 1000) {
const apiCallWithPredicateChecking = async () => {
const apiCallResult = await apiCall();
if (predicate(apiCallResult)) {
return Promise.resolve(apiCallResult);
} else {
return Promise.reject(apiCallResult);
}
};
return retryCall(apiCallWithPredicateChecking, retry, delay);
}
function retryCall(fn: () => Promise<any>, retry: number = 30, delay: number = 1000): Promise<any> {
const pause = (duration) => new Promise((res) => setTimeout(res, duration));
const run = (retries) => fn().catch((err) => (retries > 1 ? pause(delay).then(() => run(retries - 1)) : Promise.reject(err)));
return run(retry);
}

View File

@ -0,0 +1,84 @@
/*!
* Copyright © 2005-2023 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
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser, ElementFinder, protractor } from 'protractor';
import { waitUntilElementHasValue, waitUntilElementIsClickable, waitUntilElementIsVisible } from './browser-visibility';
export async function click(elementToClick: ElementFinder): Promise<void> {
try {
await waitUntilElementIsVisible(elementToClick);
await waitUntilElementIsClickable(elementToClick);
await elementToClick.click();
} catch (clickErr) {
await clickScript(elementToClick);
}
}
export async function rightClick(elementFinder: ElementFinder): Promise<void> {
await browser.actions().mouseMove(elementFinder).mouseDown().mouseMove(elementFinder).perform();
await browser.actions().click(elementFinder, protractor.Button.RIGHT).perform();
}
async function clickScript(elementToClick: ElementFinder): Promise<void> {
await browser.executeScript(`arguments[0].scrollIntoView();`, elementToClick);
await browser.executeScript(`arguments[0].click();`, elementToClick);
}
export async function getInputValue(elementFinder: ElementFinder): Promise<string> {
const present = await waitUntilElementIsVisible(elementFinder);
if (present) {
return browser.executeScript(`return arguments[0].value`, elementFinder);
} else {
console.error(`Get Input value ${elementFinder.locator().toString()} not present`);
return '';
}
}
export async function getUrl(url: string, timeout: number = 10000): Promise<any> {
return browser.get(url, timeout);
}
export async function clearSendKeys(elementFinder: ElementFinder, text: string = '', sleepTime: number = 0): Promise<void> {
await click(elementFinder);
await elementFinder.sendKeys('');
await elementFinder.clear();
if (sleepTime === 0) {
await elementFinder.sendKeys(text);
} else {
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < text.length; i++) {
await elementFinder.sendKeys(text[i]);
await browser.sleep(sleepTime);
}
}
try {
if (text !== protractor.Key.SPACE && text !== protractor.Key.ENTER) {
await waitUntilElementHasValue(elementFinder, text, 1000);
}
} catch (e) {
console.info(`Set value different from the input`);
}
}

View File

@ -0,0 +1,80 @@
/*!
* Copyright © 2005-2023 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
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { browser, ElementFinder, protractor } from 'protractor';
import { falseIfMissing } from 'protractor/built/util';
export async function waitUntilElementIsVisible(
elementToCheck: ElementFinder,
waitTimeout: number = 10000,
message: string = 'Element is not visible'
): Promise<any> {
return browser.wait(protractor.ExpectedConditions.visibilityOf(elementToCheck), waitTimeout, message + elementToCheck.locator());
}
export async function waitUntilElementIsNotVisible(elementToCheck: ElementFinder, waitTimeout: number = 10000): Promise<any> {
return browser.wait(
protractor.ExpectedConditions.invisibilityOf(elementToCheck),
waitTimeout,
'Element is Visible and it should not' + elementToCheck.locator()
);
}
export async function waitUntilElementIsClickable(elementToCheck: ElementFinder, waitTimeout: number = 10000): Promise<any> {
return browser.wait(
protractor.ExpectedConditions.elementToBeClickable(elementToCheck),
waitTimeout,
'Element is not Clickable ' + elementToCheck.locator()
);
}
export async function waitUntilElementIsPresent(elementToCheck: ElementFinder, waitTimeout: number = 10000): Promise<any> {
return browser.wait(protractor.ExpectedConditions.presenceOf(elementToCheck), waitTimeout, 'Element is not present ' + elementToCheck.locator());
}
export async function waitUntilElementIsNotPresent(elementToCheck: ElementFinder, waitTimeout: number = 10000): Promise<any> {
return browser.wait(protractor.ExpectedConditions.stalenessOf(elementToCheck), waitTimeout, 'Element is present ' + elementToCheck.locator());
}
function textToBePresentInElementValue(elementFinder: ElementFinder, text: string) {
const hasText = async () =>
browser.executeScript(`return arguments[0].value`, elementFinder).then((actualText: string) => actualText.indexOf(text) > -1, falseIfMissing);
return protractor.ExpectedConditions.and(protractor.ExpectedConditions.presenceOf(elementFinder), hasText);
}
export async function waitUntilElementHasValue(elementToCheck: ElementFinder, elementValue, waitTimeout: number = 10000): Promise<any> {
return browser.wait(
textToBePresentInElementValue(elementToCheck, elementValue),
waitTimeout,
`Element doesn't have a value ${elementValue} ${elementToCheck.locator()}`
);
}
export async function waitUntilElementHasText(elementToCheck: ElementFinder, text, waitTimeout: number = 10000): Promise<any> {
return browser.wait(
protractor.ExpectedConditions.textToBePresentInElement(elementToCheck, text),
waitTimeout,
`Element doesn't have the text ${text} ${elementToCheck.locator()}`
);
}

View File

@ -27,3 +27,8 @@ export * from './repo-client/repo-client';
export * from './admin-actions';
export * from './user-actions';
export * from './utils';
export * from './browser-visibility';
export * from './browser-actions';
export * from './api';
export * from './logger';
export * from './test-element';

View File

@ -0,0 +1,88 @@
/*!
* Copyright © 2005-2023 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/>.
*/
/* eslint-disable @typescript-eslint/naming-convention */
export const infoColor = '\x1b[36m%s\x1b[0m';
export const logColor = '\x1b[35m%s\x1b[0m';
export const warnColor = '\x1b[33m%s\x1b[0m';
export const errorColor = '\x1b[31m%s\x1b[0m';
export type LOG_LEVEL = 'TRACE' | 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'SILENT';
export class LogLevelsEnum extends Number {
static TRACE: number = 5;
static DEBUG: number = 4;
static INFO: number = 3;
static WARN: number = 2;
static ERROR: number = 1;
static SILENT: number = 0;
}
export const logLevels: { level: LogLevelsEnum; name: LOG_LEVEL }[] = [
{ level: LogLevelsEnum.TRACE, name: 'TRACE' },
{ level: LogLevelsEnum.DEBUG, name: 'DEBUG' },
{ level: LogLevelsEnum.INFO, name: 'INFO' },
{ level: LogLevelsEnum.WARN, name: 'WARN' },
{ level: LogLevelsEnum.ERROR, name: 'ERROR' },
{ level: LogLevelsEnum.SILENT, name: 'SILENT' }
];
export interface LoggerLike {
info(...messages: string[]): void;
log(...messages: string[]): void;
warn(...messages: string[]): void;
error(...messages: string[]): void;
}
/* eslint-disable no-console */
export class GenericLogger implements LoggerLike {
private readonly level: LogLevelsEnum;
constructor(logLevel: string) {
this.level = logLevels.find(({ name }) => name === logLevel)?.level || LogLevelsEnum.ERROR;
}
info(...messages: string[]): void {
if (this.level >= LogLevelsEnum.INFO) {
console.log(infoColor, messages.join(''));
}
}
log(...messages: string[]): void {
if (this.level >= LogLevelsEnum.TRACE) {
console.log(logColor, messages.join(''));
}
}
warn(...messages: string[]): void {
if (this.level >= LogLevelsEnum.WARN) {
console.log(warnColor, messages.join(''));
}
}
error(...messages: string[]): void {
console.log(errorColor, messages.join(''));
}
}

View File

@ -23,8 +23,7 @@
*/
import { RepoApi } from '../repo-api';
import { Logger } from '@alfresco/adf-testing';
import { Utils } from '../../../../utilities/utils';
import { Utils } from '../../../utils';
import { FavoritesApi as AdfFavoritesApi, SitesApi as AdfSiteApi, FavoriteEntry } from '@alfresco/js-api';
export class FavoritesApi extends RepoApi {
@ -103,10 +102,9 @@ export class FavoritesApi extends RepoApi {
}
async isFavoriteWithRetry(nodeId: string, data: { expect: boolean }) {
let isFavorite = false;
try {
const favorite = async () => {
isFavorite = await this.isFavorite(nodeId);
let isFavorite = await this.isFavorite(nodeId);
if (isFavorite !== data.expect) {
return Promise.reject(isFavorite);
} else {
@ -114,8 +112,9 @@ export class FavoritesApi extends RepoApi {
}
};
return await Utils.retryCall(favorite);
} catch (error) {}
return isFavorite;
} catch {
return false;
}
}
private async removeFavoriteById(nodeId: string) {
@ -150,8 +149,8 @@ export class FavoritesApi extends RepoApi {
};
return await Utils.retryCall(favoriteFiles);
} catch (error) {
Logger.error(`FavoritesApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
console.error(`FavoritesApi waitForApi : catch : `);
console.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
}

View File

@ -23,8 +23,7 @@
*/
import { RepoApi } from '../repo-api';
import { Logger } from '@alfresco/adf-testing';
import { Utils } from '../../../../utilities/utils';
import { Utils } from '../../../utils';
import { QueriesApi as AdfQueriesApi } from '@alfresco/js-api';
export class QueriesApi extends RepoApi {
@ -64,8 +63,8 @@ export class QueriesApi extends RepoApi {
return await Utils.retryCall(sites);
} catch (error) {
Logger.error(`QueriesApi waitForSites : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
console.error(`QueriesApi waitForSites : catch : `);
console.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
}

View File

@ -24,7 +24,6 @@
import { browser } from 'protractor';
import { AlfrescoApi } from '@alfresco/js-api';
import { Logger } from '@alfresco/adf-testing';
export abstract class RepoApi {
alfrescoJsApi = new AlfrescoApi();
@ -38,18 +37,18 @@ export abstract class RepoApi {
}
protected handleError(message: string, response: any) {
Logger.error(`\n--- ${message} error :`);
Logger.error('\t>>> username: ', this.username);
Logger.error('\t>>> JSON: ', JSON.stringify(browser.params.config));
console.error(`\n--- ${message} error :`);
console.error('\t>>> username: ', this.username);
console.error('\t>>> JSON: ', JSON.stringify(browser.params.config));
if (response.status && response.response) {
try {
Logger.error('\t>>> Status: ', response.status);
Logger.error('\t>>> Text: ', response.response.text);
Logger.error('\t>>> Method: ', response.response.error.method);
Logger.error('\t>>> Path: ', response.response.error.path);
console.error('\t>>> Status: ', response.status);
console.error('\t>>> Text: ', response.response.text);
console.error('\t>>> Method: ', response.response.error.method);
console.error('\t>>> Path: ', response.response.error.path);
} catch {
Logger.error('\t>>> ', response);
console.error('\t>>> ', response);
}
} else Logger.error('\t>>> ', response);
} else console.error('\t>>> ', response);
}
}

View File

@ -23,8 +23,8 @@
*/
import { RepoApi } from '../repo-api';
import { ApiUtil, Logger } from '@alfresco/adf-testing';
import { Utils } from '../../../../utilities/utils';
import { Utils } from '../../../utils';
import { waitForApi } from '../../../api';
import { SearchApi as AdfSearchApi } from '@alfresco/js-api';
export class SearchApi extends RepoApi {
@ -96,8 +96,8 @@ export class SearchApi extends RepoApi {
return await Utils.retryCall(recentFiles);
} catch (error) {
Logger.error(`SearchApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
console.error(`SearchApi waitForApi : catch : `);
console.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
@ -113,10 +113,10 @@ export class SearchApi extends RepoApi {
};
try {
await ApiUtil.waitForApi(apiCall, predicate, 30, 2500);
await waitForApi(apiCall, predicate, 30, 2500);
} catch (error) {
Logger.error(`SearchApi waitForNodes : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
console.error(`SearchApi waitForNodes : catch : `);
console.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
}

View File

@ -23,8 +23,7 @@
*/
import { RepoApi } from '../repo-api';
import { Logger } from '@alfresco/adf-testing';
import { Utils } from '../../../../utilities/utils';
import { Utils } from '../../../utils';
import { SharedlinksApi as AdfSharedlinksApi, SharedLinkEntry, SharedLinkPaging } from '@alfresco/js-api';
export class SharedLinksApi extends RepoApi {
@ -63,26 +62,6 @@ export class SharedLinksApi extends RepoApi {
return sharedLinks;
}
private async getSharedIdOfNode(fileId: string): Promise<string> {
try {
const sharedLinksEntries = (await this.getSharedLinks())?.list.entries;
const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId);
return (found || { entry: { id: null } }).entry.id;
} catch (error) {
this.handleError(`SharedLinksApi getSharedIdOfNode : catch : `, error);
return null;
}
}
async unshareFileById(fileId: string): Promise<any> {
try {
const sharedId = await this.getSharedIdOfNode(fileId);
return await this.sharedlinksApi.deleteSharedLink(sharedId);
} catch (error) {
this.handleError(`SharedLinksApi unshareFileById : catch : `, error);
}
}
private async getSharedLinks(maxItems: number = 250): Promise<SharedLinkPaging | null> {
try {
await this.apiAuth();
@ -108,31 +87,8 @@ export class SharedLinksApi extends RepoApi {
};
return Utils.retryCall(sharedFile).catch((error) => {
Logger.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error}`);
Logger.error(`\tWait timeout reached waiting for files to be shared`);
console.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error}`);
console.error(`\tWait timeout reached waiting for files to be shared`);
});
}
async waitForFilesToNotBeShared(filesIds: string[]): Promise<any> {
try {
const sharedFile = async () => {
const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId);
const foundItems = filesIds.some((id) => {
return sharedFiles.includes(id);
});
if (foundItems) {
return Promise.reject(foundItems);
} else {
return Promise.resolve(foundItems);
}
};
return await Utils.retryCall(sharedFile);
} catch (error) {
Logger.error(`SharedLinksApi waitForFilesToNotBeShared : catch : ${error}`);
Logger.error(`\tWait timeout reached waiting for files to no longer be shared`);
}
}
}

View File

@ -23,18 +23,9 @@
*/
import { RepoApi } from '../repo-api';
import { Logger } from '@alfresco/adf-testing';
import {
SiteBodyCreate,
SiteMembershipBodyUpdate,
SiteMembershipBodyCreate,
SiteEntry,
SiteMembershipRequestEntry,
SitesApi as AdfSiteApi,
SiteMemberEntry
} from '@alfresco/js-api';
import { SITE_VISIBILITY, SITE_ROLES } from '../../../../configs';
import { Utils } from '../../../../utilities/utils';
import { SiteBodyCreate, SiteMembershipBodyUpdate, SiteMembershipBodyCreate, SiteEntry, SitesApi as AdfSiteApi } from '@alfresco/js-api';
import { SITE_VISIBILITY } from '../../../../configs';
import { Utils } from '../../../utils';
export class SitesApi extends RepoApi {
sitesApi = new AdfSiteApi(this.alfrescoJsApi);
@ -80,21 +71,6 @@ export class SitesApi extends RepoApi {
}
}
async createSites(siteNames: string[], visibility?: string): Promise<SiteEntry[]> {
const sites: SiteEntry[] = [];
try {
if (siteNames && siteNames.length > 0) {
for (const siteName of siteNames) {
const site = await this.createSite(siteName, visibility);
sites.push(site);
}
}
} catch (error) {
this.handleError(`SitesApi createSites : catch : `, error);
}
return sites;
}
async deleteSite(siteId: string, permanent: boolean = true) {
try {
await this.apiAuth();
@ -151,52 +127,6 @@ export class SitesApi extends RepoApi {
}
}
async addSiteConsumer(siteId: string, userId: string): Promise<SiteMemberEntry> {
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_CONSUMER.ROLE);
}
async addSiteContributor(siteId: string, userId: string): Promise<SiteMemberEntry> {
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_CONTRIBUTOR.ROLE);
}
async addSiteCollaborator(siteId: string, userId: string): Promise<SiteMemberEntry> {
return this.addSiteMember(siteId, userId, SITE_ROLES.SITE_COLLABORATOR.ROLE);
}
async deleteSiteMember(siteId: string, userId: string) {
try {
await this.apiAuth();
return await this.sitesApi.deleteSiteMembership(siteId, userId);
} catch (error) {
this.handleError(`SitesApi deleteSiteMember : catch : `, error);
}
}
async requestToJoin(siteId: string): Promise<SiteMembershipRequestEntry | null> {
const body = {
id: siteId
};
try {
await this.apiAuth();
return await this.sitesApi.createSiteMembershipRequestForPerson('-me-', body);
} catch (error) {
this.handleError(`SitesApi requestToJoin : catch : `, error);
return null;
}
}
async hasMembershipRequest(siteId: string) {
try {
await this.apiAuth();
const requests = (await this.sitesApi.listSiteMembershipRequestsForPerson('-me-')).list.entries.map((e) => e.entry.id);
return requests.includes(siteId);
} catch (error) {
this.handleError(`SitesApi hasMembershipRequest : catch : `, error);
return null;
}
}
async waitForSitesToBeCreated(sitesIds: string[]) {
try {
const site = async () => {
@ -213,8 +143,8 @@ export class SitesApi extends RepoApi {
return await Utils.retryCall(site);
} catch (error) {
Logger.error(`SitesApi waitForSitesToBeCreated : catch : ${error}`);
Logger.error(`\tWait timeout reached waiting for sites to be created`);
console.error(`SitesApi waitForSitesToBeCreated : catch : ${error}`);
console.error(`\tWait timeout reached waiting for sites to be created`);
}
}
}

View File

@ -0,0 +1,255 @@
/*!
* Copyright © 2005-2023 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
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { by, element, ElementFinder, protractor, $, browser } from 'protractor';
import { clearSendKeys, click, getInputValue } from './browser-actions';
import {
waitUntilElementHasValue,
waitUntilElementIsNotPresent,
waitUntilElementIsNotVisible,
waitUntilElementIsPresent,
waitUntilElementIsVisible
} from './browser-visibility';
async function getAttribute(elementFinder: ElementFinder, attribute: string): Promise<string> {
await waitUntilElementIsPresent(elementFinder);
const attributeValue: string = await browser.executeScript(`return arguments[0].getAttribute(arguments[1])`, elementFinder, attribute);
return attributeValue || '';
}
async function getText(elementFinder: ElementFinder): Promise<string> {
const present = await waitUntilElementIsVisible(elementFinder);
if (present) {
let text = await elementFinder.getText();
if (text === '') {
// DO NOT REMOVE BUG sometime wrongly return empty text for cdk elements
console.info(`Use backup get text script`);
text = await this.getTextScript(elementFinder);
return text?.trim();
}
return text;
} else {
console.error(`Get Text ${elementFinder.locator().toString()} not present`);
return '';
}
}
/**
* Provides a wrapper for the most common operations with the page elements.
*/
export class TestElement {
constructor(public elementFinder: ElementFinder) {}
/**
* Create a new instance with the element located by the id
*
* @param id The id of the element
* @returns test element wrapper
*/
static byId(id: string): TestElement {
return new TestElement(element(by.id(id)));
}
/**
* Create a new instance with the element located by the CSS class name
*
* @param selector The CSS class name to lookup
* @returns test element wrapper
*/
static byCss(selector: string): TestElement {
return new TestElement($(selector));
}
/**
* Create a new instance with the element that contains specific text
*
* @param selector the CSS selector
* @param text the text within the target element
* @returns test element wrapper
*/
static byText(selector: string, text: string): TestElement {
return new TestElement(element(by.cssContainingText(selector, text)));
}
/**
* Create a new instance with the element with specific HTML tag name
*
* @param selector the HTML tag name
* @returns test element wrapper
*/
static byTag(selector: string): TestElement {
return new TestElement(element(by.tagName(selector)));
}
/**
* Performs a click on this element
*/
async click() {
return click(this.elementFinder);
}
/**
* Checks that an element is present on the DOM of a page and visible
*
* @param waitTimeout How long to wait for the condition to be true
*/
async isVisible(waitTimeout?: number): Promise<boolean> {
try {
await waitUntilElementIsVisible(this.elementFinder, waitTimeout);
return true;
} catch {
return false;
}
}
/**
* Waits until the element is present on the DOM of a page and visible
*
* @param waitTimeout How long to wait for the condition to be true
*/
async waitVisible(waitTimeout?: number): Promise<any> {
return waitUntilElementIsVisible(this.elementFinder, waitTimeout);
}
/**
* Waits until the element is either invisible or not present on the DOM
*
* @param waitTimeout How long to wait for the condition to be true
*/
async waitNotVisible(waitTimeout?: number): Promise<any> {
return waitUntilElementIsNotVisible(this.elementFinder, waitTimeout);
}
/**
* Checks that an element is present on the DOM of a page
*
* @param waitTimeout How long to wait for the condition to be true
*/
async isPresent(waitTimeout?: number): Promise<boolean> {
try {
await waitUntilElementIsPresent(this.elementFinder, waitTimeout);
return true;
} catch {
return false;
}
}
/**
* Waits until the element is present on the DOM of a page
*
* @param waitTimeout How long to wait for the condition to be true
*/
async waitPresent(waitTimeout?: number): Promise<any> {
return waitUntilElementIsPresent(this.elementFinder, waitTimeout);
}
/**
* Waits until the element is not attached to the DOM of a page
*
* @param waitTimeout How long to wait for the condition to be true
*/
async waitNotPresent(waitTimeout?: number): Promise<any> {
return waitUntilElementIsNotPresent(this.elementFinder, waitTimeout);
}
/**
* Waits until the given text is present in the elements value
*
* @param value the text to check
*/
async waitHasValue(value: string): Promise<any> {
return waitUntilElementHasValue(this.elementFinder, value);
}
/**
* Query whether the DOM element represented by this instance is enabled.
*/
async isEnabled(): Promise<boolean> {
return this.elementFinder.isEnabled();
}
/**
* Query whether the DOM element represented by this instance is disabled.
*/
async isDisabled(): Promise<boolean> {
return !(await this.elementFinder.isEnabled());
}
/**
* Test whether this element is currently displayed.
*/
async isDisplayed(): Promise<boolean> {
try {
await this.elementFinder.isDisplayed();
return true;
} catch {
return false;
}
}
/**
* Query for the value of the given attribute of the element.
*
* @param attributeName The name of the attribute to query.
*/
async getAttribute(attributeName: string): Promise<string> {
return getAttribute(this.elementFinder, attributeName);
}
/**
* Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace.
*/
async getText(): Promise<string> {
return getText(this.elementFinder);
}
/**
* Gets the `value` attribute for the given input element
*
* @returns input value
*/
getInputValue(): Promise<string> {
return getInputValue(this.elementFinder);
}
/**
* Enter the text
*
* @param text the text to enter
*/
async typeText(text: string): Promise<void> {
await clearSendKeys(this.elementFinder, text);
}
/**
* Clears the input using Ctrl+A and Backspace combination
*/
async clearInput() {
await this.elementFinder.clear();
await this.elementFinder.sendKeys(' ', protractor.Key.CONTROL, 'a', protractor.Key.NULL, protractor.Key.BACK_SPACE);
}
}

View File

@ -22,7 +22,6 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { Logger } from '@alfresco/adf-testing';
import { AlfrescoApi, Comment, CommentsApi, NodesApi, TrashcanApi, SitesApi, SharedlinksApi } from '@alfresco/js-api';
import { browser } from 'protractor';
@ -168,18 +167,18 @@ export class UserActions {
}
protected handleError(message: string, response: any) {
Logger.error(`\n--- ${message} error :`);
Logger.error('\t>>> username: ', this.username);
Logger.error('\t>>> JSON: ', JSON.stringify(browser.params.config));
console.error(`\n--- ${message} error :`);
console.error('\t>>> username: ', this.username);
console.error('\t>>> JSON: ', JSON.stringify(browser.params.config));
if (response.status && response.response) {
try {
Logger.error('\t>>> Status: ', response.status);
Logger.error('\t>>> Text: ', response.response.text);
Logger.error('\t>>> Method: ', response.response.error.method);
Logger.error('\t>>> Path: ', response.response.error.path);
console.error('\t>>> Status: ', response.status);
console.error('\t>>> Text: ', response.response.text);
console.error('\t>>> Method: ', response.response.error.method);
console.error('\t>>> Path: ', response.response.error.path);
} catch {
Logger.error('\t>>> ', response);
console.error('\t>>> ', response);
}
} else Logger.error('\t>>> ', response);
} else console.error('\t>>> ', response);
}
}

View File

@ -23,10 +23,10 @@
*/
import { browser, protractor, ElementFinder, ExpectedConditions as EC, by, until, WebElement } from 'protractor';
import { BrowserVisibility, Logger } from '@alfresco/adf-testing';
import { BROWSER_WAIT_TIMEOUT } from '../configs';
import * as path from 'path';
import * as fs from 'fs';
import { waitUntilElementIsPresent, waitUntilElementIsVisible } from './browser-visibility';
const StreamZip = require('node-stream-zip');
const crypto = require('crypto');
@ -55,7 +55,7 @@ export async function waitForStaleness(element: ElementFinder, errorMessage?: st
export const isPresentAndEnabled = async (element: ElementFinder): Promise<boolean> => {
try {
await BrowserVisibility.waitUntilElementIsPresent(element);
await waitUntilElementIsPresent(element);
return element.isEnabled();
} catch (error) {
return false;
@ -64,7 +64,7 @@ export const isPresentAndEnabled = async (element: ElementFinder): Promise<boole
export const isPresentAndDisplayed = async (element: ElementFinder): Promise<boolean> => {
try {
await BrowserVisibility.waitUntilElementIsVisible(element);
await waitUntilElementIsVisible(element);
return true;
} catch (error) {
return false;
@ -131,7 +131,7 @@ export class Utils {
if (fileExists) {
fs.rename(oldFilePath, newFilePath, function (err: any) {
if (err) {
Logger.error(`==== rename err : failed to rename file from ${oldName} to ${newName} : `, err);
console.error(`==== rename err : failed to rename file from ${oldName} to ${newName} : `, err);
}
});
}
@ -148,7 +148,7 @@ export class Utils {
});
await zip.on('error', (err: any) => {
Logger.error(`=== unzip err : failed to unzip ${filename} - ${unzippedName} :`, err);
console.error(`=== unzip err : failed to unzip ${filename} - ${unzippedName} :`, err);
});
await zip.on('ready', async () => {

View File

@ -5,7 +5,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
eval libs=( "@alfresco/adf-core"
"@alfresco/adf-content-services"
"@alfresco/adf-extensions"
"@alfresco/adf-testing"
"@alfresco/adf-cli"
"@alfresco/eslint-plugin-eslint-angular"
)

View File

@ -21,8 +21,6 @@
"typeRoots": ["node_modules/@types"],
"lib": ["es2019", "dom"],
"paths": {
"@alfresco/adf-testing": ["../alfresco-ng2-components/lib/testing"],
"@alfresco/adf-testing/shared": ["../alfresco-ng2-components/lib/testing/src/lib/shared"],
"@alfresco/playwright-shared": ["projects/aca-playwright-shared/src/index.ts"],
"@alfresco/adf-core": ["../alfresco-ng2-components/lib/core/index.ts"],
"@alfresco/adf-core/*": ["../alfresco-ng2-components/lib/core/*/public-api.ts"],