feat(PageController): make sure page is indexed before calling actions on elements
This commit is contained in:
@@ -80,6 +80,9 @@ export class PageController extends EventTarget {
|
||||
/** last time the tree was updated */
|
||||
private lastTimeUpdate = 0
|
||||
|
||||
/** Whether the tree has been indexed at least once */
|
||||
private isIndexed = false
|
||||
|
||||
/** Visual mask overlay for blocking user interaction during automation */
|
||||
private mask: InstanceType<typeof import('./mask/SimulatorMask').SimulatorMask> | null = null
|
||||
private maskReady: Promise<void> | null = null
|
||||
@@ -196,6 +199,9 @@ export class PageController extends EventTarget {
|
||||
this.elementTextMap.clear()
|
||||
this.elementTextMap = dom.getElementTextMap(this.simplifiedHTML)
|
||||
|
||||
// Mark as indexed - now element actions are allowed
|
||||
this.isIndexed = true
|
||||
|
||||
// Restore mask blocking
|
||||
if (this.mask) {
|
||||
this.mask.wrapper.style.pointerEvents = 'auto'
|
||||
@@ -215,11 +221,22 @@ export class PageController extends EventTarget {
|
||||
|
||||
// ======= Element Actions =======
|
||||
|
||||
/**
|
||||
* Ensure the tree has been indexed before any index-based operation.
|
||||
* Throws if updateTree() hasn't been called yet.
|
||||
*/
|
||||
private assertIndexed(): void {
|
||||
if (!this.isIndexed) {
|
||||
throw new Error('DOM tree not indexed. Can not perform actions on elements.')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Click element by index
|
||||
*/
|
||||
async clickElement(index: number): Promise<ActionResult> {
|
||||
try {
|
||||
this.assertIndexed()
|
||||
const element = getElementByIndex(this.selectorMap, index)
|
||||
const elemText = this.elementTextMap.get(index)
|
||||
await clickElement(element)
|
||||
@@ -249,6 +266,7 @@ export class PageController extends EventTarget {
|
||||
*/
|
||||
async inputText(index: number, text: string): Promise<ActionResult> {
|
||||
try {
|
||||
this.assertIndexed()
|
||||
const element = getElementByIndex(this.selectorMap, index)
|
||||
const elemText = this.elementTextMap.get(index)
|
||||
await inputTextElement(element, text)
|
||||
@@ -270,6 +288,7 @@ export class PageController extends EventTarget {
|
||||
*/
|
||||
async selectOption(index: number, optionText: string): Promise<ActionResult> {
|
||||
try {
|
||||
this.assertIndexed()
|
||||
const element = getElementByIndex(this.selectorMap, index)
|
||||
const elemText = this.elementTextMap.get(index)
|
||||
await selectOptionElement(element as HTMLSelectElement, optionText)
|
||||
@@ -298,6 +317,8 @@ export class PageController extends EventTarget {
|
||||
try {
|
||||
const { down, numPages, pixels, index } = options
|
||||
|
||||
this.assertIndexed()
|
||||
|
||||
const scrollAmount = pixels ?? numPages * (down ? 1 : -1) * window.innerHeight
|
||||
|
||||
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
||||
@@ -327,6 +348,8 @@ export class PageController extends EventTarget {
|
||||
try {
|
||||
const { right, pixels, index } = options
|
||||
|
||||
this.assertIndexed()
|
||||
|
||||
const scrollAmount = pixels * (right ? 1 : -1)
|
||||
|
||||
const element = index !== undefined ? getElementByIndex(this.selectorMap, index) : null
|
||||
@@ -394,6 +417,7 @@ export class PageController extends EventTarget {
|
||||
this.selectorMap.clear()
|
||||
this.elementTextMap.clear()
|
||||
this.simplifiedHTML = '<EMPTY>'
|
||||
this.isIndexed = false
|
||||
this.mask?.dispose()
|
||||
this.mask = null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user