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

fix(action): keyboard and div extracting #304

Merged
merged 7 commits into from
Jan 21, 2025
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
10 changes: 9 additions & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'dotenv/config';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import dotenv from 'dotenv';
import { matchYamlFiles, parseProcessArgs } from './cli-utils';
import { playYamlFiles } from './yaml-runner';

Expand All @@ -9,6 +11,12 @@ Promise.resolve(
const welcome = '\nWelcome to @midscene/cli\n';
console.log(welcome);

const dotEnvConfigFile = join(process.cwd(), '.env');
if (existsSync(dotEnvConfigFile)) {
console.log(`loading .env file from ${dotEnvConfigFile}`);
dotenv.config({ path: dotEnvConfigFile });
}

if (options.url) {
console.error(
'the cli mode is no longer supported, please use yaml file instead. See https://midscenejs.com/automate-with-scripts-in-yaml for more information. Sorry for the inconvenience.',
Expand Down
13 changes: 5 additions & 8 deletions packages/web-integration/src/chrome-extension/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,14 @@ export default class ChromeExtensionProxyPage implements AbstractPage {
commands: ['selectAll'],
});

await this.sendCommandToDebugger('Input.dispatchKeyEvent', {
type: 'keyDown',
key: 'Backspace',
code: 'Backspace',
});

await this.sendCommandToDebugger('Input.dispatchKeyEvent', {
type: 'keyUp',
key: 'Backspace',
code: 'Backspace',
commands: ['selectAll'],
});

await sleep(100);

await this.keyboard.press('Backspace');
}

mouse = {
Expand Down
5 changes: 5 additions & 0 deletions packages/web-integration/src/extractor/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ export function visibleRect(
return false;
}

// check if the element is hidden by an ancestor
let parent: HTMLElement | Node | null = el;
while (parent && parent !== document.body) {
if (!(parent instanceof HTMLElement)) {
Expand All @@ -319,6 +320,10 @@ export function visibleRect(
return false;
}
}
// if the parent is a fixed element, stop the search
if (parentStyle.position === 'fixed') {
break;
}
parent = parent.parentElement;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/web-integration/src/puppeteer/agent-launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export async function puppeteerAgentForTarget(
...(isWindows ? [] : ['--no-sandbox', '--disable-setuid-sandbox']),
'--disable-features=PasswordLeakDetection',
'--disable-save-password-bubble',
'--start-maximized',
`--window-size=${width},${height}`,
],
});
freeFn.push({
Expand Down
27 changes: 20 additions & 7 deletions packages/web-integration/src/puppeteer/base-page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Point, Size } from '@midscene/core';
import { getTmpFile } from '@midscene/core/utils';
import { getTmpFile, sleep } from '@midscene/core/utils';
import { base64Encoded } from '@midscene/shared/img';
import type { Page as PlaywrightPage } from 'playwright';
import type { Page as PuppeteerPage } from 'puppeteer';
Expand Down Expand Up @@ -79,9 +79,14 @@ export class Page<

get mouse() {
return {
click: async (x: number, y: number, options?: { button: MouseButton }) =>
click: async (
x: number,
y: number,
options?: { button?: MouseButton; count?: number },
) =>
this.underlyingPage.mouse.click(x, y, {
button: options?.button || 'left',
count: options?.count || 1,
}),
wheel: async (deltaX: number, deltaY: number) => {
if (this.pageType === 'puppeteer') {
Expand Down Expand Up @@ -118,18 +123,26 @@ export class Page<
return;
}

await this.mouse.click(element.center[0], element.center[1]);

const isMac = process.platform === 'darwin';
if (isMac) {
await this.underlyingPage.keyboard.down('Meta');
await this.underlyingPage.keyboard.press('a');
await this.underlyingPage.keyboard.up('Meta');
if (this.pageType === 'puppeteer') {
// https://github.com/segment-boneyard/nightmare/issues/810#issuecomment-452669866
await this.mouse.click(element.center[0], element.center[1], {
count: 3,
});
} else {
await this.mouse.click(element.center[0], element.center[1]);
await this.underlyingPage.keyboard.down('Meta');
await this.underlyingPage.keyboard.press('a');
await this.underlyingPage.keyboard.up('Meta');
}
} else {
await this.mouse.click(element.center[0], element.center[1]);
await this.underlyingPage.keyboard.down('Control');
await this.underlyingPage.keyboard.press('a');
await this.underlyingPage.keyboard.up('Control');
}
await sleep(100);
await this.keyboard.press('Backspace');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ test('ai todo', async ({ ai, aiQuery }) => {
test.setTimeout(1000 * 50);
}

await ai('Enter "Learn" in the task box, don\'t press enter');
await ai('Enter "Happy Birthday" in the task box');
await ai('Enter "Learn" in the task box');

await ai(
'Add "JS today" to base on the existing content(important) of the task box, then press enter',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,14 @@ describe(
});

it('search engine', async () => {
const { originPage, reset } = await launchPage('https://www.bing.com/');
const { originPage, reset } = await launchPage('https://www.baidu.com/');
const mid = new PuppeteerAgent(originPage);
await mid.aiAction('type "AI 101" in search box');
await mid.aiAction(
'type "AI 101" in search box, hit Enter, wait 2s, click the second result, wait 4s',
'type "Hello world" in search box, hit Enter, wait 2s, click the second result, wait 4s',
);

await mid.aiWaitFor('there are some search results');
await mid.aiWaitFor('there are some search results about "Hello world"');

await reset();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,27 @@ exports[`extractor > basic 1`] = `
},
"content": "hidden label",
},
{
"attributes": {
"htmlTagName": "<div>",
"nodeType": "TEXT Node",
},
"content": "i am fixed child content",
},
{
"attributes": {
"htmlTagName": "<span>",
"nodeType": "TEXT Node",
},
"content": "abcd efg",
},
{
"attributes": {
"htmlTagName": "<div>",
"nodeType": "TEXT Node",
},
"content": "content editable div content. We should collect the parent.",
},
{
"attributes": {
"htmlTagName": "<div>",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,23 @@ <h3>Form</h3>
<span>hidden label</span>
</label>

<!-- element under position: fixed -->
<div style="position: absolute; top: -100px; left: -100px; width: 100px; height: 100px; background-color: #ccc; overflow: hidden;">
<div style="position: fixed; top: 200px; right: 40px; width: 200px; height: 100px; background-color: #EEE;">
<div>i am fixed child content</div>
</div>
</div>

<!-- div with content editable -->
<div contenteditable="true" class="content-editable-div" style="position: relative; width: 300px; height: 100px; background-color: #ccc;">
<!-- I am a content editable div. -->
<span>abcd efg</span>
<div style="position: absolute; left: 0px; bottom: 0; width: 100%; height: 50px; background-color: #EEE;">
content editable div content. We should collect the parent.
</div>
</div>


<!-- absolute parent with width 0 -->
<div style="position: absolute; top: 0px; left: 0; width: 100%; height: 0;">
<div>absolute child content</div>
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.
Loading