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

Run screenshot tests on mobile #645

Merged
merged 13 commits into from
Nov 19, 2024
2 changes: 1 addition & 1 deletion resources/lib/responsive/responsive_hv.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
position:fixed;
margin-top:0px;
right:0;
z-index:9999;
z-index:5000;
}

.hamburger {
Expand Down
248 changes: 138 additions & 110 deletions tests/desktop/normal/screenshot.spec.ts
Original file line number Diff line number Diff line change
@@ -1,116 +1,144 @@
import { test, expect, PageScreenshotOptions } from "@playwright/test";
import { Helioviewer } from "../../page_objects/helioviewer";
import * as fs from "fs";

// loading of wrong url , is creating problems
test("Screenshot button should toggle screenshot drawer", async ({ page, context }, info) => {
let hv = new Helioviewer(page);

await hv.Load();
await hv.CloseAllNotifications();

await hv.screenshot.toggleScreenshotDrawer();

expect(await page.screenshot()).toMatchSnapshot("screenshot-drawer-enabled.png");

await hv.screenshot.toggleScreenshotDrawer();

expect(await page.screenshot()).toMatchSnapshot("screenshot-drawer-disabled.png");
});

// create multiple screenshots and compare them
test("Create a new screenshot and view it and close it", async ({ page, context, browserName }, info) => {
test.fixme(
browserName === "webkit",
"We couldn't be able to trigger download event for webkit, skipping this test now"
import { MobileView, DesktopView, HelioviewerFactory, MobileInterface } from "page_objects/helioviewer_interface";

[MobileView, DesktopView].forEach((view) => {
// loading of wrong url , is creating problems
test(
`[${view.name}] Screenshot button should toggle screenshot drawer`,
{ tag: [view.tag] },
async ({ page }, info) => {
let hv = HelioviewerFactory.Create(view, page, info) as MobileInterface;

await hv.Load();
await hv.CloseAllNotifications();
const screenshotMask: PageScreenshotOptions = {
mask: [
page.locator("#screenshot-manager-container .status"),
page.locator("#hvmobtime_td #time"),
page.locator("#hvmobdate_td #date")
]
};

await hv.screenshot.toggleScreenshotDrawer();

expect(await page.screenshot(screenshotMask)).toMatchSnapshot("screenshot-drawer-enabled.png");

await hv.screenshot.toggleScreenshotDrawer();

expect(await page.screenshot(screenshotMask)).toMatchSnapshot("screenshot-drawer-disabled.png");
}
);

let hv = new Helioviewer(page, info);
// Mask the screenshot creation time.
// The screenshot may expect "1 second ago"
// but the actual result may be "2 seconds ago". causing the test to fail.
const screenshotMask: PageScreenshotOptions = { mask: [page.locator("#screenshot-manager-container .status")] };

// load helioviewer
await hv.Load();
await hv.CloseAllNotifications();

// open screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// create a full-screen screenshot
await hv.screenshot.createFullScreenshot();
await hv.screenshot.waitForScreenshotCompleteNotifitication();

// assert there should be one screenshot in drawer
await hv.screenshot.assertScreenshotCountFromDrawer(1);

// download and save screenshot from notification ( by clicking your screenshot ready in jgrowl messsage)
const screenshotFileFromNotification = await hv.screenshot.downloadScreenshotFromNotification();
const screenshot_notification_report_file = info.outputPath("screenshot_from_notification.png");
await fs.promises.writeFile(
screenshot_notification_report_file,
Buffer.from(screenshotFileFromNotification, "base64")
// create multiple screenshots and compare them
test(
`[${view.name}] Create a new screenshot and view it and close it`,
{ tag: [view.tag] },
async ({ page, context, browserName }, info) => {
test.fixme(
browserName === "webkit",
"We couldn't be able to trigger download event for webkit, skipping this test now"
);

let hv = HelioviewerFactory.Create(view, page, info) as MobileInterface;
// Mask the screenshot creation time.
// The screenshot may expect "1 second ago"
// but the actual result may be "2 seconds ago". causing the test to fail.
const screenshotMask: PageScreenshotOptions = {
mask: [
page.locator("#screenshot-manager-container .status"),
page.locator("#hvmobtime_td #time"),
page.locator("#hvmobdate_td #date")
]
};

// load helioviewer
await hv.Load();
await hv.CloseAllNotifications();

// open screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// create a full-screen screenshot
await hv.screenshot.createFullScreenshot();
await hv.screenshot.waitForScreenshotCompleteNotifitication();

// assert there should be one screenshot in drawer
await hv.screenshot.assertScreenshotCountFromDrawer(1);

// download and save screenshot from notification ( by clicking your screenshot ready in jgrowl messsage)
const screenshotFileFromNotification = await hv.screenshot.downloadScreenshotFromNotification();
const screenshot_notification_report_file = info.outputPath("screenshot_from_notification.png");
await fs.promises.writeFile(
screenshot_notification_report_file,
Buffer.from(screenshotFileFromNotification, "base64")
);
await info.attach("screenshot-notification", { path: screenshot_notification_report_file });

// close the notification
await hv.CloseAllNotifications();

// On mobile, we have to close the drawer to close notifications.
// So open the screenshots back up to check that the screenshot is in the list.
if (view == MobileView) {
await hv.OpenScreenshotsDialog();
}
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// now click the created screenshot link and see the screenshot in full screen
await hv.screenshot.viewScreenshotFromScreenshotHistory(1, true);
expect(await page.screenshot()).toMatchSnapshot("view-first-screenshot.png");

// Close the screenshot from X
// compare the test snapshot with the one we have created for
await hv.screenshot.closeScreenshotView();
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// See screenshot again
await hv.screenshot.viewScreenshotFromScreenshotHistory(1);
await hv.WaitForLoadingComplete();

// now download screenshot from screenshot view via download button
const screenshotFileFromScreenshotView = await hv.screenshot.downloadScreenshotFromViewScreenshotFeature();
const screenshot_view_screenshot_report_file = info.outputPath("screenshot_view_screenshot.png");
await fs.promises.writeFile(
screenshot_view_screenshot_report_file,
Buffer.from(screenshotFileFromScreenshotView, "base64")
);
await info.attach("screenshot-view-screenshot", { path: screenshot_view_screenshot_report_file });

// compare screenshots downloaded from different sources
await expect(screenshotFileFromNotification).toBe(screenshotFileFromScreenshotView);

// Close screenshot from X in the view
await hv.screenshot.closeScreenshotView();

// Close screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// This test snapshot should match the initial state
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("screenshot-drawer-disabled.png");

// Reopen screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// Test snapshot with initial first screenshot created view
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// Now add another snapshot
await hv.screenshot.createFullScreenshot();
await hv.screenshot.waitForScreenshotCompleteNotifitication();
await hv.CloseAllNotifications();

// assert there should be two screenshots in drawer
await hv.screenshot.assertScreenshotCountFromDrawer(2);

expect(await page.screenshot(screenshotMask)).toMatchSnapshot("second-screenshot-created.png");

// assert there should be two screenshots in drawer
await hv.screenshot.viewScreenshotFromScreenshotHistory(1, true);

expect(await page.screenshot()).toMatchSnapshot("view-first-screenshot.png");
}
);
await info.attach("screenshot-notification", { path: screenshot_notification_report_file });

// close the notification
await hv.CloseAllNotifications();

expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// now click the created screenshot link and see the screenshot in full screen
await hv.screenshot.viewScreenshotFromScreenshotHistory(1, true);
expect(await page.screenshot()).toMatchSnapshot("view-first-screenshot.png");

// Close the screenshot from X
// compare the test snapshot with the one we have created for
await hv.screenshot.closeScreenshotView();
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// See screenshot again
await hv.screenshot.viewScreenshotFromScreenshotHistory(1);
await hv.WaitForImageLoad();

// now download screenshot from screenshot view via download button
const screenshotFileFromScreenshotView = await hv.screenshot.downloadScreenshotFromViewScreenshotFeature();
const screenshot_view_screenshot_report_file = info.outputPath("screenshot_view_screenshot.png");
await fs.promises.writeFile(
screenshot_view_screenshot_report_file,
Buffer.from(screenshotFileFromScreenshotView, "base64")
);
await info.attach("screenshot-view-screenshot", { path: screenshot_view_screenshot_report_file });

// compare screenshots downloaded from different sources
await expect(screenshotFileFromNotification).toBe(screenshotFileFromScreenshotView);

// Close screenshot from X in the view
await hv.screenshot.closeScreenshotView();

// Close screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// This test snapshot should match the initial state
expect(await page.screenshot()).toMatchSnapshot("screenshot-drawer-disabled.png");

// Reopen screenshot drawer
await hv.screenshot.toggleScreenshotDrawer();

// Test snapshot with initial first screenshot created view
expect(await page.screenshot(screenshotMask)).toMatchSnapshot("first-screenshot-created.png");

// Now add another snapshot
await hv.screenshot.createFullScreenshot();
await hv.screenshot.waitForScreenshotCompleteNotifitication();
await hv.CloseAllNotifications();

// assert there should be two screenshots in drawer
await hv.screenshot.assertScreenshotCountFromDrawer(2);

expect(await page.screenshot(screenshotMask)).toMatchSnapshot("second-screenshot-created.png");

// assert there should be two screenshots in drawer
await hv.screenshot.viewScreenshotFromScreenshotHistory(1, true);

expect(await page.screenshot()).toMatchSnapshot("view-first-screenshot.png");
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 15 additions & 15 deletions tests/mobile/regression/youtube.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ const YOUTUBE_VIDEO_JSON = [
id: "TvlW5",
url: "http://www.youtube.com/watch?v=wvMXYeot2uk",
thumbnails: {
icon: "https://api.helioviewer.org/cache/movies/2024/08/19/TvlW5/preview-icon.png",
small: "https://api.helioviewer.org/cache/movies/2024/08/19/TvlW5/preview-small.png",
medium: "https://api.helioviewer.org/cache/movies/2024/08/19/TvlW5/preview-medium.png",
large: "https://api.helioviewer.org/cache/movies/2024/08/19/TvlW5/preview-large.png",
full: "https://api.helioviewer.org/cache/movies/2024/08/19/TvlW5/preview-full.png"
icon: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
small: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
medium: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
large: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
full: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png"
},
published: "2024-08-19 15:35:15",
title: "LASCO C2/C3 (2024-08-17 11:00:07 - 2024-08-19 10:36:07 UTC)",
Expand All @@ -112,11 +112,11 @@ const YOUTUBE_VIDEO_JSON = [
id: "qvlW5",
url: "http://www.youtube.com/watch?v=Je_DraAKq34",
thumbnails: {
icon: "https://api.helioviewer.org/cache/movies/2024/08/19/qvlW5/preview-icon.png",
small: "https://api.helioviewer.org/cache/movies/2024/08/19/qvlW5/preview-small.png",
medium: "https://api.helioviewer.org/cache/movies/2024/08/19/qvlW5/preview-medium.png",
large: "https://api.helioviewer.org/cache/movies/2024/08/19/qvlW5/preview-large.png",
full: "https://api.helioviewer.org/cache/movies/2024/08/19/qvlW5/preview-full.png"
icon: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
small: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
medium: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
large: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
full: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png"
},
published: "2024-08-19 15:20:32",
title: "AIA 304 (2024-08-18 22:09:41 - 2024-08-19 01:09:29 UTC)",
Expand All @@ -136,11 +136,11 @@ const YOUTUBE_VIDEO_JSON = [
id: "FvlW5",
url: "http://www.youtube.com/watch?v=W5AC7bFEcVM",
thumbnails: {
icon: "https://api.helioviewer.org/cache/movies/2024/08/19/FvlW5/preview-icon.png",
small: "https://api.helioviewer.org/cache/movies/2024/08/19/FvlW5/preview-small.png",
medium: "https://api.helioviewer.org/cache/movies/2024/08/19/FvlW5/preview-medium.png",
large: "https://api.helioviewer.org/cache/movies/2024/08/19/FvlW5/preview-large.png",
full: "https://api.helioviewer.org/cache/movies/2024/08/19/FvlW5/preview-full.png"
icon: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
small: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
medium: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
large: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png",
full: "https://helioviewer.org/resources/images/viewyoutube_icon_transp.png"
},
published: "2024-08-19 15:18:47",
title: "AIA 304 (2024-08-18 23:37:05 - 2024-08-19 05:35:53 UTC)",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions tests/page_objects/helioviewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,10 @@ class Helioviewer implements DesktopInterface {
await this.page.locator("#news-button").click();
}

async OpenScreenshotsDialog(): Promise<void> {
return await this.screenshot.toggleScreenshotDrawer();
}

/**
* Click youtube button in top controls to see the shared youtube videos
* @returns {Promise<void>}
Expand Down
7 changes: 7 additions & 0 deletions tests/page_objects/helioviewer_interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { HelioviewerMinimal } from "./helioviewer_minimal";
import { HvMobile } from "./mobile_hv";
import { ImageLayer } from "./image_layer";
import { URLShare, MobileURLShare } from "./urlshare";
import { Screenshot } from "./screenshot";
import { EventTree } from "./event_tree";

/**
Expand Down Expand Up @@ -56,12 +57,18 @@ interface MinimalInterface extends EmbedInterface {}
*/
interface MobileInterface extends MinimalInterface {
urlshare: URLShare | MobileURLShare;
screenshot: Screenshot;

/**
* Opens the drawer which contains image layer information
*/
OpenImageLayerDrawer(): Promise<void>;

/**
* Opens the screenshot UI
*/
OpenScreenshotsDialog(): Promise<void>;

/**
* Opens the drawer which contains featres & events selections
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/page_objects/mobile_hv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ImageLayer } from "./image_layer";
import { ScaleIndicator } from "./scale_indicator";
import { MobileInterface } from "./helioviewer_interface";
import { MobileURLShare } from "./urlshare";
import { MobileScreenshot } from "./screenshot";
import { EventTree } from "./event_tree";

class HvMobile implements MobileInterface {
Expand All @@ -28,11 +29,17 @@ class HvMobile implements MobileInterface {
/** #hvmobdrawerclose - Ref to button which closes the control drawer */
private _drawer_close_btn: Locator;
public urlshare: MobileURLShare;
public screenshot: MobileScreenshot;

constructor(page: Page, info: TestInfo | null = null) {
this.page = page;
this.hv = new Helioviewer(page, info);
this.urlshare = new MobileURLShare(page);
this.screenshot = new MobileScreenshot(page, {
IsScreenshotDialogOpen: () => this.IsScreenshotDialogOpen(),
OpenScreenshotDialog: () => this.OpenScreenshotsDialog(),
CloseMenu: () => this.CloseScreenshotsDialog()
});
this._controls = this.page.locator(".hvbottombar");
this._image_drawer = this.page.locator("#accordion-images");
this._image_drawer_btn = this.page.locator('[drawersec="accordion-images"]');
Expand Down Expand Up @@ -213,12 +220,18 @@ class HvMobile implements MobileInterface {
await this.TapIfVisible(this.page.locator("#hv-drawer-movies .hvmobmenuclose"));
}

async IsScreenshotDialogOpen(): Promise<boolean> {
return await this.page.getByText("Take a Screenshot").isVisible();
}

/**
* Open the screenshot creation dialog
*/
async OpenScreenshotsDialog() {
await this.OpenSidebar();
await this.TapIfVisible(this.page.getByText("Create a screenshot."));
// Wait for animation to complete
await this.page.waitForTimeout(500);
}

async CloseScreenshotsDialog() {
Expand Down
Loading
Loading