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
68 changes: 68 additions & 0 deletions src/Commands/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,74 @@ private static bool TryParseWebCommandOptions(WebCommand command, string[] args,
{
parsed = false;
}
else if (arg == "--click")
{
var selector = GetInputOptionArgs(i + 1, args, max: 1).FirstOrDefault();
if (string.IsNullOrEmpty(selector))
throw new CommandLineException($"Missing selector for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.Click) { Selector = selector });
i += 1;
}
else if (arg == "--move")
{
var coords = GetInputOptionArgs(i + 1, args, max: 2).ToList();
if (coords.Count != 2)
throw new CommandLineException($"Missing x,y coordinates for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.MouseMove)
{
X = ValidateInt(arg, coords[0], "x coordinate"),
Y = ValidateInt(arg, coords[1], "y coordinate")
});
i += 2;
}
else if (arg == "--drag")
{
var selectors = GetInputOptionArgs(i + 1, args, max: 2).ToList();
if (selectors.Count != 2)
throw new CommandLineException($"Missing source and target selectors for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.DragDrop)
{
Selector = selectors[0],
TargetSelector = selectors[1]
});
i += 2;
}
else if (arg == "--scroll")
{
var coords = GetInputOptionArgs(i + 1, args, max: 2).ToList();
if (coords.Count != 2)
throw new CommandLineException($"Missing x,y coordinates for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.Scroll)
{
X = ValidateInt(arg, coords[0], "x coordinate"),
Y = ValidateInt(arg, coords[1], "y coordinate")
});
i += 2;
}
else if (arg == "--type")
{
var text = GetInputOptionArgs(i + 1, args, max: 1).FirstOrDefault();
if (string.IsNullOrEmpty(text))
throw new CommandLineException($"Missing text for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.TypeText) { Value = text });
i += 1;
}
else if (arg == "--key")
{
var key = GetInputOptionArgs(i + 1, args, max: 1).FirstOrDefault();
if (string.IsNullOrEmpty(key))
throw new CommandLineException($"Missing key for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.KeyPress) { Value = key });
i += 1;
}
else if (arg == "--shortcut")
{
var shortcut = GetInputOptionArgs(i + 1, args, max: 1).FirstOrDefault();
if (string.IsNullOrEmpty(shortcut))
throw new CommandLineException($"Missing shortcut for {arg}");
command.InputActions.Add(new WebInputAction(WebInputActionType.Shortcut) { Value = shortcut });
i += 1;
}
else if (arg == "--interactive")
{
command.Interactive = true;
Expand Down
29 changes: 29 additions & 0 deletions src/Commands/WebCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public WebCommand()
SaveFolder = null;

PageInstructionsList = new();
InputActions = new();
}

public bool Interactive { get; set; }
Expand All @@ -35,6 +36,34 @@ public WebCommand()
public string SaveFolder { get; set; }

public List<Tuple<string, string>> PageInstructionsList;
public List<WebInputAction> InputActions;

public string SavePageOutput { get; set; }
}

public class WebInputAction
{
public WebInputActionType Type { get; set; }
public string Selector { get; set; }
public string Value { get; set; }
public int? X { get; set; }
public int? Y { get; set; }
public string TargetSelector { get; set; }

public WebInputAction(WebInputActionType type)
{
Type = type;
}
}

public enum WebInputActionType
{
Click,
MouseMove,
DragDrop,
Scroll,
KeyPress,
TypeText,
Shortcut
}
}
61 changes: 61 additions & 0 deletions src/Helpers/WebInputHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Microsoft.Playwright;
using System;
using System.Threading.Tasks;

namespace mdx.Helpers
{
public class WebInputHelper
{
private IPage _page;

public WebInputHelper(IPage page)
{
_page = page;
}

public async Task Click(string selector)
{
await _page.ClickAsync(selector);
}

public async Task MouseMove(int x, int y)
{
await _page.Mouse.MoveAsync(x, y);
}

public async Task MouseDown()
{
await _page.Mouse.DownAsync();
}

public async Task MouseUp()
{
await _page.Mouse.UpAsync();
}

public async Task DragAndDrop(string sourceSelector, string targetSelector)
{
await _page.DragAndDropAsync(sourceSelector, targetSelector);
}

public async Task Scroll(int x, int y)
{
await _page.Mouse.WheelAsync(x, y);
}

public async Task PressKey(string key)
{
await _page.Keyboard.PressAsync(key);
}

public async Task TypeText(string text)
{
await _page.Keyboard.TypeAsync(text);
}

public async Task SendShortcut(string shortcut)
{
await _page.Keyboard.PressAsync(shortcut);
}
}
}
27 changes: 27 additions & 0 deletions src/assets/help/web get inputs.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
INPUT MOUSE AND KEYBOARD OPTIONS

The following options allow interaction with web pages using mouse and keyboard inputs:

Mouse Input Options:
--click "selector" Click on the element matching the selector
--move <x> <y> Move mouse to coordinates x,y
--drag "src" "target" Drag element from source selector to target selector
--scroll <x> <y> Scroll the page by x and y pixels

Keyboard Input Options:
--type "text" Type the specified text
--key "key" Press a single key (e.g. "Enter", "Tab")
--shortcut "combo" Send keyboard shortcut (e.g. "Control+C")

Examples:
Click a button:
mdx web get "https://example.com" --click "#submit-button"

Fill out a form:
mdx web get "https://example.com/form" --click "#username" --type "myuser" --click "#password" --type "mypass" --click "#submit"

Drag and drop:
mdx web get "https://example.com/drag" --drag "#source" "#target"

Scroll down page:
mdx web get "https://example.com" --scroll 0 500
5 changes: 5 additions & 0 deletions src/assets/help/web get.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ EXAMPLES

mdx web get "https://learnxinyminutes.com/docs/yaml/" --strip

EXAMPLE 3: Interact with a web page using mouse and keyboard inputs

mdx web get "https://example.com" --click "#button" --type "text"

SEE ALSO

mdx help web get options
mdx help web get examples
mdx help web get inputs

mdx help web search
mdx help web search examples
Expand Down
26 changes: 26 additions & 0 deletions tests/web-input-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
options:
- "--click"
- "#submit-button"
- "--type"
- "test input"
- "--key"
- "Enter"
- "--scroll"
- "0"
- "100"
- "--move"
- "200"
- "300"
- "--drag"
- "#source-elem"
- "#target-elem"
- "--shortcut"
- "Control+A"

expected:
- status: 0
- stderr: ""
- stdout: |-
Processing input actions on dummy test page...
Success!