Skip to content
Open
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
8 changes: 8 additions & 0 deletions packages/web-integration/src/static/static-agent.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { Agent as PageAgent } from '@midscene/core/agent';
import type { UIContext } from '@midscene/core';
import type StaticPage from './static-page';

export class StaticPageAgent extends PageAgent {
private readonly staticPage: StaticPage;

constructor(page: StaticPage) {
// Disable report generation in browser environment to avoid Node.js fs module errors
super(page, { generateReport: false });
this.staticPage = page;
this.dryMode = true;
}

override async getUIContext(): Promise<UIContext> {
return this.staticPage.getUIContext();
}
}
40 changes: 39 additions & 1 deletion packages/web-integration/src/static/static-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
ScreenshotRef,
UIContext,
} from '@midscene/core';
import { ScreenshotItem } from '@midscene/core';
import type { AbstractInterface } from '@midscene/core/device';
import {
type InputPrimitives,
Expand All @@ -25,9 +26,12 @@ type SerializedStaticScreenshot = {

type StaticPageUIContext = Omit<
UIContext,
'deprecatedDpr' | 'screenshot'
'deprecatedDpr' | 'screenshot' | 'screenshotSequence'
> & {
screenshot: UIContext['screenshot'] | SerializedStaticScreenshot;
screenshotSequence?: Array<
UIContext['screenshot'] | SerializedStaticScreenshot
>;
};

function screenshotBase64FromContext(
Expand All @@ -50,10 +54,38 @@ function screenshotBase64FromContext(
);
}

function screenshotItemFromContext(
screenshot: StaticPageUIContext['screenshot'],
): ScreenshotItem {
if (screenshot instanceof ScreenshotItem) {
return screenshot;
}

const capturedAt =
typeof screenshot.capturedAt === 'number'
? screenshot.capturedAt
: Date.now();
return ScreenshotItem.create(
screenshotBase64FromContext(screenshot),
capturedAt,
);
}

function normalizeUIContext(uiContext: StaticPageUIContext): UIContext {
return {
...uiContext,
screenshot: screenshotItemFromContext(uiContext.screenshot),
screenshotSequence: uiContext.screenshotSequence?.map(
screenshotItemFromContext,
),
};
}

export default class StaticPage implements AbstractInterface {
interfaceType = 'static';

private uiContext: StaticPageUIContext;
private normalizedUIContext?: UIContext;
readonly inputPrimitives: InputPrimitives = {
pointer: {
tap: async () => ThrowNotImplemented('Tap'),
Expand All @@ -78,6 +110,11 @@ export default class StaticPage implements AbstractInterface {
this.uiContext = uiContext;
}

getUIContext(): UIContext {
this.normalizedUIContext ??= normalizeUIContext(this.uiContext);
return this.normalizedUIContext;
}

actionSpace(): DeviceAction[] {
// Return available actions for static page - they will throw "not implemented" errors when executed
// but need to be available for planning phase
Expand Down Expand Up @@ -175,5 +212,6 @@ export default class StaticPage implements AbstractInterface {

updateContext(newContext: StaticPageUIContext): void {
this.uiContext = newContext;
this.normalizedUIContext = undefined;
}
}
29 changes: 28 additions & 1 deletion packages/web-integration/tests/unit-test/static-page.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ScreenshotItem } from '@midscene/core';
import { describe, expect, it } from '@rstest/core';
import { StaticPage } from '../../src/static';
import { StaticPage, StaticPageAgent } from '../../src/static';

const screenshotBase64 = 'data:image/png;base64,abc123';

Expand Down Expand Up @@ -53,4 +53,31 @@ describe('StaticPage', () => {
'serialized reference without base64 data',
);
});

it('lets StaticPageAgent reuse the prepared UI context', async () => {
const capturedAt = 123;
const page = new StaticPage(
createContext({ base64: screenshotBase64, capturedAt }),
);
const agent = new StaticPageAgent(page);

const context = await agent.getUIContext();

expect(context.shotSize).toEqual({ width: 800, height: 600 });
expect(context.shrunkShotToLogicalRatio).toBe(1);
expect(context.screenshot).toBeInstanceOf(ScreenshotItem);
expect(context.screenshot.base64).toBe(screenshotBase64);
expect(context.screenshot.capturedAt).toBe(capturedAt);

const updatedScreenshotBase64 = 'data:image/png;base64,updated';
page.updateContext(
createContext({ base64: updatedScreenshotBase64, capturedAt: 456 }),
);

const updatedContext = await agent.getUIContext();

expect(updatedContext).not.toBe(context);
expect(updatedContext.screenshot.base64).toBe(updatedScreenshotBase64);
expect(updatedContext.screenshot.capturedAt).toBe(456);
});
});
Loading