Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MWPW-147876 Improve SharePoint editing #349

Merged
merged 2 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,5 @@ configs/test-html-results/
browserstackSetupConfig.json
configs/playwright-browserstack-sdk.config.js
playwright-browserstack-sdk.config.temp.json

.auth/
81 changes: 65 additions & 16 deletions selectors/bacom-blog/sharepoint.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,88 @@ export default class Sharepoint {
this.insertPageBreakButton = this.iframe.locator('#InsertPageBreak');
this.homeButton = this.iframe.locator('#Home');
this.undoButton = this.iframe.locator('#UndoRedo > button:first-of-type');
this.editingElement = this.iframe.locator('#WACViewPanel_EditingElement');
this.documentTitle = this.iframe.locator('button#documentTitle');
this.dialogPanel = this.iframe.locator('#WACDialogPanel');
this.dialogText = this.iframe.locator('#WACDialogTextPanel');
this.navButton = this.iframe.locator('#FishBowlNavButton');
this.pageBreaks = this.iframe.locator('span.PageBreakTextSpan');
}

/**
* @description Adds a page break by selecting the insert page break button under
* the inserts tab and then saves the file.
* @description Gets the text of the dialog box.
* @returns {Promise<string>} The text of the dialog box.
*/
async getDialogText() {
if (await this.dialogText.isVisible()) {
const dialogText = await this.dialogText.textContent();
return dialogText;
}
return '';
}

/**
* @description Waits for the page to load by checking for key elements.
* @returns {Promise<boolean>} True if the page is loaded, false otherwise.
*/
async waitForLoad() {
await this.page.waitForLoadState('domcontentloaded');
await expect(this.homeButton).toBeVisible({ timeout: 1000 * 30 });
await expect(this.navButton).toBeVisible({ timeout: 1000 * 30 });

// check that there is no dialog box blocking the page
return !await this.dialogPanel.isVisible();
}

/**
* @description Saves the file by simulating the keyboard shortcut Control+S.
*/
async saveFile() {
await this.page.keyboard.press('Control+S');

const saveStatus = await this.documentTitle.locator('div[aria-label]').first();
await expect.soft(saveStatus).toHaveAttribute('aria-label', /.*Last saved: Just now/, { timeout: 1000 * 30 });
}

/**
* @description Adds a page break by selecting the insert page break button under the inserts tab.
*/
async addPageBreak() {
const pageBreakCount = await this.pageBreaks.count();
// Make sure the button is visible before clicking
await expect(async () => {
await this.insertButton.click();
await expect(this.insertPageBreakButton).toBeVisible();
await this.insertPageBreakButton.click();
await this.homeButton.click();
await expect(this.undoButton).toBeVisible();
await expect(this.undoButton).toBeEnabled();
await expect(this.insertPageBreakButton).toBeVisible({ timeout: 1000 });
}).toPass();

await this.page.keyboard.press('Control+S');
await this.page.waitForTimeout(2000);
// We can not trust the button to work immediately
await expect(async () => {
if (await this.insertPageBreakButton.isDisabled()) {
await this.editingElement.focus();
await this.page.keyboard.press('ArrowDown');
}
if (await this.insertPageBreakButton.isEnabled()) {
await this.insertPageBreakButton.click();
}

await expect(this.pageBreaks).not.toHaveCount(pageBreakCount, { timeout: 1000 });
}).toPass();
}

/**
* @description Undos the previous change in session by selecting the undo button
* under the home tab and then saves the file.
* @description Undos all previous changes in session by selecting the undo button under the home tab.
*/
async undoChanges() {
if (!this.undoButton.isVisible()) this.homeButton.click();
await expect(async () => {
await this.homeButton.click();
await expect(this.undoButton).toBeVisible({ timeout: 1000 });
}).toPass();

await expect(this.undoButton).toBeEnabled();

await expect(async () => {
await this.undoButton.click();
await expect(this.undoButton).toBeDisabled();
await expect(this.undoButton).toBeDisabled({ timeout: 1000 });
}).toPass();

await this.page.keyboard.press('Control+S');
await this.page.waitForTimeout(2000);
}
}
56 changes: 40 additions & 16 deletions tests/bacom-blog/edit-sharepoint-doc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,81 @@ import fs from 'fs';
import Sharepoint from '../../selectors/bacom-blog/sharepoint.page.js';

const sharepointBacomBlogDrafts = 'https://adobe.sharepoint.com/sites/BizWeb/Shared%20Documents/Forms/AllItems.aspx';
const bacomBlogAdminUrl = 'https://admin.hlx.page/status/adobecom/bacom-blog/main/';
const bacomBlogHlx = 'https://main--bacom-blog--adobecom.hlx.live/';
const bacomBlogAdminUrl = 'https://admin.hlx.page/status/adobecom/bacom-blog/main';
const data = JSON.parse(fs.readFileSync('./data/bacom-blog/stagedBlogUrls.json', 'utf8'));
const testPages = Object.keys(data).map((key) => data[key][1]);

let page;
let context;
let sharepoint;

const authFile = 'tests/bacom-blog/.auth/user.json';

test.describe('Sharepoint editing', { tag: '@sp' }, async () => {
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
const options = fs.existsSync(authFile) ? { storageState: authFile } : {};
context = await browser.newContext(options);
page = await context.newPage();
sharepoint = new Sharepoint(page);

// TODO: Automated okta login
// For now, we need to sign into okta manually
await page.goto(sharepointBacomBlogDrafts);
await page.waitForTimeout(160000);
await page.waitForURL(sharepointBacomBlogDrafts, { timeout: 1000 * 60 * 2 });

await context.storageState({ path: authFile });
});

test.afterAll(async () => {
await page.close();
});

testPages.forEach(async (url) => {
await test(`Editing a docx in sharepoint - ${url} `, async () => {
await test.setTimeout(10000 * 1000);
await test.setTimeout(1000 * 60 * 2); // Set each test timeout to 2 minutes

await test.step('1. Go to the docx.', async () => {
const relative = url.replace(bacomBlogHlx, '');
const adminPage = `${bacomBlogAdminUrl}${relative}?editUrl=auto`;
await page.goto(adminPage);
await page.waitForLoadState('domcontentloaded');
const adminPageContent = await page.locator('pre').textContent();
const docxUrl = JSON.parse(adminPageContent).edit.url;
const { pathname } = new URL(url);
const adminPage = `${bacomBlogAdminUrl}${pathname}?editUrl=auto`;
const response = await page.evaluate(async (api) => fetch(api)
.then((req) => (req.ok ? req.json() : Promise.reject(req))), adminPage);
const docxUrl = response?.edit.url;

console.log(`[Test page]: ${url}`);
console.log(`[Admin page]: ${adminPage}`);
console.log(`[Docx Url]: ${docxUrl}\n`);

if (docxUrl === undefined) {
console.log(`Unable to find edit url for ${url}\n`);
test.skip();
test.skip(true, 'Unable to find edit url');
}

await page.goto(docxUrl);
await page.waitForLoadState('domcontentloaded');
});

await test.step('2. Make an edit and save.', async () => {
await test.step('2. Load the docx.', async () => {
const loaded = await sharepoint.waitForLoad();
if (!loaded) {
const status = await sharepoint.getDialogText();
console.log(status);
test.skip(true, status);
}
});

await test.step('3. Make an edit.', async () => {
await sharepoint.addPageBreak();
});

await test.step('3. Undo the change and save.', async () => {
await test.step('4. save document.', async () => {
await sharepoint.saveFile();
});

await test.step('5. Undo the change.', async () => {
await sharepoint.undoChanges();
});

await test.step('6. save document.', async () => {
await sharepoint.saveFile();
});
});
});
});
Loading