Skip to content

Commit

Permalink
refactor(roku, dom): removed cyclic dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
dlenroc committed Dec 11, 2023
1 parent 1c3c1b0 commit ab00202
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 569 deletions.
8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@

Roku SDK is a set of strongly typed libraries with minimal dependencies for managing Roku devices

## Getting Started

If you don't know where to start

- [@dlenroc/roku](./packages/roku#readme)

If you are interested in a specific part

- [@dlenroc/roku-debug-server](/packages/debug-server#readme)
- [@dlenroc/roku-developer-server](/packages/developer-server#readme)
- [@dlenroc/roku-dom](/packages/dom#readme)
Expand Down
5 changes: 4 additions & 1 deletion packages/dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@
"build": "tsc --build --force tsconfig.build.json"
},
"dependencies": {
"@dlenroc/roku": "^2.0.0",
"css-select": "^5.1.0",
"css-select-base-adapter": "^0.1.1",
"libxmljs2": "^0.33.0"
},
"peerDependencies": {
"@dlenroc/roku-ecp": "^2.0.0",
"@dlenroc/roku-odc": "^2.0.0"
}
}
23 changes: 14 additions & 9 deletions packages/dom/src/Document.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SDK } from '@dlenroc/roku';
import { Element as XMLElement, parseXml } from 'libxmljs2';
import { keypress, queryAppUI } from '@dlenroc/roku-ecp';
import { getAppUI } from '@dlenroc/roku-odc';
import { parseXml, type Element as XMLElement } from 'libxmljs2';
import { Element } from './Element.js';
import { RokuError } from './Error.js';
import type { SDK } from './internal/SDK.ts';
import { KEYBOARD } from './internal/selectors.js';

const rootXML = '<app-ui></app-ui>';
Expand Down Expand Up @@ -33,7 +34,7 @@ export class Document extends Element {
if (keyboard) {
await keyboard.clear();
} else {
throw new RokuError('Keyboard must be visible to clear the field');
throw new Error('Keyboard must be visible to clear the field');
}
}

Expand All @@ -44,7 +45,9 @@ export class Document extends Element {
await keyboard.type(text);
} else {
for (const char of text) {
await this.sdk.ecp.keypress({ key: char as any });
await keypress(this.sdk.ecp, {
key: `LIT_${encodeURIComponent(char)}`,
});
}
}
}
Expand All @@ -56,7 +59,9 @@ export class Document extends Element {
await keyboard.append(text);
} else {
for (const char of text) {
await this.sdk.ecp.keypress({ key: char as any });
await keypress(this.sdk.ecp, {
key: `LIT_${encodeURIComponent(char)}`,
});
}
}
}
Expand All @@ -65,11 +70,11 @@ export class Document extends Element {
let xml;

if (this.context === 'ECP') {
xml = await this.sdk.ecp.queryAppUI();
xml = await queryAppUI(this.sdk.ecp);
} else if (this.context === 'ODC') {
xml = await this.sdk.odc.getAppUI(this.fields);
xml = await getAppUI(this.sdk.odc, { fields: this.fields! });
} else {
throw new RokuError(`Unknown context ${this.context}`);
throw new Error(`Unknown context ${this.context}`);
}

if (xml !== this.xml) {
Expand Down
35 changes: 18 additions & 17 deletions packages/dom/src/Element.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { SDK } from '@dlenroc/roku';
import { Element as XMLElement, Node as XMLNode } from 'libxmljs2';
import { keypress } from '@dlenroc/roku-ecp';
import { Element as XMLElement, type Node as XMLNode } from 'libxmljs2';
import { performance } from 'node:perf_hooks';
import { Document } from './Document.js';
import { RokuError } from './Error.js';
import type { Document } from './Document.ts';
import type { SDK } from './internal/SDK.ts';
import { selectAll, selectOne } from './internal/css-select.js';
import { BUTTON, DIALOG, KEYBOARD, LABEL } from './internal/selectors.js';

Expand Down Expand Up @@ -198,14 +198,14 @@ export class Element {

async select() {
await this.focus();
await this.sdk.ecp.keypress({ key: 'Select' });
await keypress(this.sdk.ecp, { key: 'Select' });
}

async focus() {
const move = async (key: any) => {
const { path, attributes } = this.document.focusedElement;

await this.sdk.ecp.keypress({ key });
await keypress(this.sdk.ecp, { key });

const moved = await retrying({
timeout: 5000,
Expand All @@ -231,7 +231,7 @@ export class Element {
});

if (!moved) {
throw new RokuError('Focused element did not change after navigation');
throw new Error('Focused element did not change after navigation');
}
};

Expand Down Expand Up @@ -263,6 +263,7 @@ export class Element {
continue;
}

console.log(targetBounds, sourceBounds);
if (targetBounds.y < sourceBounds.y) {
moved = true;
await move('Up');
Expand All @@ -280,7 +281,7 @@ export class Element {
}

if (!this.isInFocusChain) {
throw new RokuError('Could not focus');
throw new Error('Could not focus');
}
}

Expand Down Expand Up @@ -403,14 +404,14 @@ async function appendOrSetText(element: Element, text: string, clear: boolean) {
if (input && (cursor?.bounds?.x || keyboard.attributes['text'])) {
const inputLength = input.attributes['text']?.length || 0;
for (let i = 0; i <= inputLength; i++) {
await element.sdk.ecp.keypress({ key: 'Backspace' });
await keypress(element.sdk.ecp, { key: 'Backspace' });
}
}
}

if (text) {
for (const char of text) {
await element.sdk.ecp.keypress({ key: char as any });
await keypress(element.sdk.ecp, { key: char as any });
}
}

Expand All @@ -427,7 +428,7 @@ async function appendOrSetText(element: Element, text: string, clear: boolean) {
if (keyboard) {
await appendOrSetText(keyboard, text, clear);
} else {
throw new RokuError(
throw new Error(
'Keyboard dialog did not appear after pressing `Select` on element'
);
}
Expand All @@ -442,7 +443,7 @@ async function appendOrSetText(element: Element, text: string, clear: boolean) {
if (submitButton) {
await submitButton.select();
} else {
await element.sdk.ecp.keypress({ key: 'Enter' });
await keypress(element.sdk.ecp, { key: 'Enter' });
}

// Wait for the keyboard to disappear
Expand All @@ -452,20 +453,20 @@ async function appendOrSetText(element: Element, text: string, clear: boolean) {
5
));
if (isKeyboardClosed) {
throw new RokuError('Keyboard dialog did not disappear');
throw new Error('Keyboard dialog did not disappear');
}
}

function normalizeNode(node: XMLNode | null): XMLElement | null {
function normalizeNode(node: XMLElement | null): XMLElement | null {
if (node instanceof XMLElement) {
return node;
}

const element = node?.parent();
const element = (node as unknown as XMLNode)?.parent();
return element instanceof XMLElement ? element : null;
}

function normalizeNodes(nodes: XMLNode[]): XMLElement[] {
function normalizeNodes(nodes: XMLElement[]): XMLElement[] {
const elements = [];

for (const node of nodes) {
Expand All @@ -488,7 +489,7 @@ async function retrying<Type>(options: {
command: () => Promise<Type>;
validate: (result?: Type, error?: any) => boolean;
}): Promise<Type> {
const duration = 500;
const duration = 200;
const endTimestamp = performance.now() + options.timeout;

while (true) {
Expand Down
6 changes: 0 additions & 6 deletions packages/dom/src/Error.ts

This file was deleted.

7 changes: 7 additions & 0 deletions packages/dom/src/internal/SDK.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { Executor as ECPExecutor } from '@dlenroc/roku-ecp';
import type { Executor as ODCExecutor } from '@dlenroc/roku-odc';

export type SDK = {
ecp: ECPExecutor;
odc: ODCExecutor;
};
4 changes: 2 additions & 2 deletions packages/dom/src/internal/css-select.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as CssSelect from 'css-select';
// @ts-ignore
import BaseAdapter from 'css-select-base-adapter';
import { Element as XMLElement, Node as XMLNode } from 'libxmljs2';
import { Element as XMLElement } from 'libxmljs2';

const XmlAdapter = BaseAdapter({
isTag(node: XMLNode): boolean {
isTag(node: XMLElement): boolean {
return node instanceof XMLElement;
},

Expand Down
9 changes: 7 additions & 2 deletions packages/dom/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"noEmit": false,
"composite": true,
"declarationMap": false,
"noEmit": false,
"sourceMap": false,
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["./src"],
"references": [{ "path": "../roku/tsconfig.build.json" }]
"references": [
{ "path": "../ecp/tsconfig.build.json" },
{ "path": "../odc/tsconfig.build.json" }
]
}
Loading

0 comments on commit ab00202

Please sign in to comment.