From 30b6dcc8e6b45ff62e2b43b44601906b18e43f53 Mon Sep 17 00:00:00 2001 From: abrichr Date: Wed, 26 Aug 2026 12:52:28 -0400 Subject: [PATCH 1/5] Add GUI automation discovery guides --- data/compare/api.json | 80 ++++++ data/compare/autohotkey.json | 82 +++++++ data/compare/computer-use-agents.json | 2 +- data/compare/playwright.json | 80 ++++++ data/compare/power-automate.json | 2 +- data/compare/selenium.json | 80 ++++++ data/compare/uipath.json | 2 +- data/comparisons.js | 111 ++++++++- pages/compare.js | 12 + pages/compare/[slug].js | 26 +- pages/guides/automate-repetitive-gui-tasks.js | 228 ++++++++++++++++++ public/llms-full.txt | 61 ++++- public/llms.txt | 7 +- public/sitemap.xml | 30 +++ tests/comparisonPages.test.js | 4 + tests/growthGenerators.test.js | 13 +- tests/guiAutomationGuide.test.js | 49 ++++ 17 files changed, 834 insertions(+), 35 deletions(-) create mode 100644 data/compare/api.json create mode 100644 data/compare/autohotkey.json create mode 100644 data/compare/playwright.json create mode 100644 data/compare/selenium.json create mode 100644 pages/guides/automate-repetitive-gui-tasks.js create mode 100644 tests/guiAutomationGuide.test.js diff --git a/data/compare/api.json b/data/compare/api.json new file mode 100644 index 00000000..bd1fbd82 --- /dev/null +++ b/data/compare/api.json @@ -0,0 +1,80 @@ +{ + "slug": "api", + "competitor": "a supported API", + "positioningSummary": "Use a supported API whenever it exposes the full operation. Use OpenAdapt only for the UI-bound remainder, and use a read-only API as the verifier when one exists.", + "dimensions": [ + { + "id": "determinism-on-drift", + "label": "Determinism when interfaces drift", + "openadapt": "A compiled workflow re-resolves targets from retained evidence, produces a governed repair proposal, or halts when the visible interface changes beyond its contract.", + "them": "An API bypasses interface layout entirely. Its callers depend on the service's published request, response, authentication, and versioning contract instead of screen geometry.", + "sources": [ + {"label": "HTTP semantics", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "cost-per-run", + "label": "Cost per run", + "openadapt": "A healthy compiled run makes no model call, but GUI execution still needs a browser, desktop, or remote session.", + "them": "A direct HTTP API exchanges request and response messages without GUI actuation. Provider charges and rate limits are service-specific.", + "sources": [ + {"label": "HTTP messages", "url": "https://www.rfc-editor.org/rfc/rfc9110.html#name-messages"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "verification-of-effects", + "label": "Verification of business effects", + "openadapt": "OpenAdapt separates actuation from verification. A read-only API, SQL query, file check, or second interface can prove the effect after the GUI action.", + "them": "A response status describes how the server handled the request. For consequential work, the caller can add a separate read-back or postcondition check instead of treating request acceptance as the complete business result.", + "sources": [ + {"label": "HTTP status code semantics", "url": "https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "halting-behavior", + "label": "Halting behavior", + "openadapt": "The workflow refuses before actuation when identity, target, or policy checks fail. If an action may have been dispatched but its effect cannot be proved, it returns RECONCILIATION_REQUIRED without a blind retry.", + "them": "The client owns error handling, idempotency, retries, and reconciliation. HTTP defines conditional request and method semantics, but the application must use them correctly.", + "sources": [ + {"label": "HTTP conditional requests", "url": "https://www.rfc-editor.org/rfc/rfc9110.html#name-conditional-requests"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "data-locality", + "label": "Data locality", + "openadapt": "The GUI runtime and retained evidence can stay inside a customer-controlled boundary.", + "them": "The client sends request messages to the API server. The service's deployment contract governs the data after it crosses that network boundary.", + "sources": [ + {"label": "HTTP messages", "url": "https://www.rfc-editor.org/rfc/rfc9110.html#name-messages"}, + {"label": "OpenAdapt trust center", "url": "https://openadapt.ai/security"} + ] + }, + { + "id": "scope", + "label": "Scope: browser, desktop, RDP/Citrix", + "openadapt": "OpenAdapt handles operations that exist only through browser, native desktop, or customer-qualified remote-window interfaces.", + "them": "An API is the best fit when the service owner exposes the complete operation through a supported machine interface. HTTP defines the exchange, while the service defines the available business operations.", + "sources": [ + {"label": "OpenAdapt comparison overview", "url": "https://openadapt.ai/compare"}, + {"label": "HTTP semantics", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"} + ] + } + ], + "strengths": [ + {"text": "A direct API bypasses screen rendering, focus, pointer movement, and visual target resolution.", "source": {"label": "HTTP semantics", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"}}, + {"text": "Requests and responses can carry typed, machine-readable data and explicit status codes.", "source": {"label": "HTTP message semantics", "url": "https://www.rfc-editor.org/rfc/rfc9110.html#name-messages"}}, + {"text": "Authentication and conditional requests have standard protocol semantics that clients can test directly.", "source": {"label": "HTTP authentication and conditions", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"}}, + {"text": "The service owner can support the integration contract as the user interface changes.", "source": null} + ], + "faq": [ + { + "question": "Should I use OpenAdapt when an API already does the job?", + "answer": "No. Use the supported API for the complete operation. OpenAdapt fits the steps the API does not expose, and the API can still serve as an independent verifier after GUI actuation.", + "sources": [{"label": "OpenAdapt comparison guide", "url": "https://openadapt.ai/compare/api"}] + } + ] +} diff --git a/data/compare/autohotkey.json b/data/compare/autohotkey.json new file mode 100644 index 00000000..e2e7ab11 --- /dev/null +++ b/data/compare/autohotkey.json @@ -0,0 +1,82 @@ +{ + "slug": "autohotkey", + "competitor": "AutoHotkey", + "positioningSummary": "AutoHotkey is a fast local tool for Windows hotkeys and macros. OpenAdapt is for shared workflows that need retained evidence, governed repair, qualification, and independent effect verification.", + "dimensions": [ + { + "id": "determinism-on-drift", + "label": "Determinism when interfaces drift", + "openadapt": "A compiled workflow resolves targets from retained evidence and halts or proposes a reviewable repair when the interface leaves its contract.", + "them": "An AutoHotkey script deterministically sends the commands its author wrote. Coordinate and active-window macros can break under layout changes; control-oriented scripts can be more stable when the application exposes useful controls.", + "sources": [ + {"label": "AutoHotkey Send", "url": "https://www.autohotkey.com/docs/v2/lib/Send.htm"}, + {"label": "AutoHotkey ControlClick", "url": "https://www.autohotkey.com/docs/v2/lib/ControlClick.htm"}, + {"label": "AutoHotkey ControlSend", "url": "https://www.autohotkey.com/docs/v2/lib/ControlSend.htm"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "cost-per-run", + "label": "Cost per run", + "openadapt": "The MIT local runtime has no per-run license fee, and a healthy compiled run makes no model call.", + "them": "AutoHotkey is free and open source. A normal local macro has no per-run license fee and makes no model call.", + "sources": [ + {"label": "AutoHotkey license", "url": "https://www.autohotkey.com/docs/v2/license.htm"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "verification-of-effects", + "label": "Verification of business effects", + "openadapt": "A consequential run returns VERIFIED only after an independent check proves the intended change in the system of record.", + "them": "AutoHotkey can read window and control state, but the author must build any business-level read-back, file check, database query, or other effect oracle.", + "sources": [ + {"label": "AutoHotkey ControlSend", "url": "https://www.autohotkey.com/docs/v2/lib/ControlSend.htm"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "halting-behavior", + "label": "Halting behavior", + "openadapt": "Identity, target, policy, and effect checks define explicit halt conditions, and uncertain delivery is preserved for reconciliation.", + "them": "The script decides when to stop. AutoHotkey supplies exceptions, return values, window waits, and process control, but it does not impose a business transaction outcome contract.", + "sources": [ + {"label": "AutoHotkey WinWait", "url": "https://www.autohotkey.com/docs/v2/lib/WinWait.htm"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "data-locality", + "label": "Data locality", + "openadapt": "Recordings, compiled bundles, and run evidence can stay in a customer-controlled boundary.", + "them": "AutoHotkey runs on the Windows machine. Data stays local unless the script sends it to another service.", + "sources": [ + {"label": "AutoHotkey overview", "url": "https://www.autohotkey.com/"}, + {"label": "OpenAdapt trust center", "url": "https://openadapt.ai/security"} + ] + }, + { + "id": "scope", + "label": "Scope: browser, desktop, RDP/Citrix", + "openadapt": "The runtime covers browser, native desktop, and customer-qualified remote-window workflows, with current scope bound to published qualification evidence.", + "them": "AutoHotkey targets Windows input, windows, and controls. It can drive whatever is visible to that Windows session, but remote and browser semantics remain the script author's responsibility.", + "sources": [ + {"label": "AutoHotkey ControlClick", "url": "https://www.autohotkey.com/docs/v2/lib/ControlClick.htm"}, + {"label": "OpenAdapt qualification evidence", "url": "https://docs.openadapt.ai/get-started/what-works-today/"} + ] + } + ], + "strengths": [ + {"text": "Send can simulate keystrokes and mouse clicks in the active window.", "source": {"label": "AutoHotkey Send", "url": "https://www.autohotkey.com/docs/v2/lib/Send.htm"}}, + {"text": "ControlClick and ControlSend can target a window control without relying only on the current pointer position.", "source": {"label": "AutoHotkey ControlClick", "url": "https://www.autohotkey.com/docs/v2/lib/ControlClick.htm"}}, + {"text": "Small hotkey, remapping, and text-expansion scripts are quick to write and easy for one operator to run.", "source": {"label": "AutoHotkey quick reference", "url": "https://www.autohotkey.com/docs/v2/"}}, + {"text": "The runtime is free, open source, and local to Windows.", "source": {"label": "AutoHotkey license", "url": "https://www.autohotkey.com/docs/v2/license.htm"}} + ], + "faq": [ + { + "question": "When should a personal macro become an OpenAdapt workflow?", + "answer": "The change makes sense when other people depend on it, failures become hard to see, the target drifts often, or a wrong business result costs more than a visible macro error.", + "sources": [{"label": "OpenAdapt comparison guide", "url": "https://openadapt.ai/compare/autohotkey"}] + } + ] +} diff --git a/data/compare/computer-use-agents.json b/data/compare/computer-use-agents.json index 95b81f40..66eb6c24 100644 --- a/data/compare/computer-use-agents.json +++ b/data/compare/computer-use-agents.json @@ -44,7 +44,7 @@ "id": "verification-of-effects", "label": "Verification of business effects", "openadapt": - "Every consequential run ends VERIFIED or HALTED based on an independent check of the system of record, with silent incorrect success counted as a tracked failure metric in published evidence.", + "VERIFIED requires an independent check of the system of record. Refusal before effect and RECONCILIATION_REQUIRED after uncertain delivery remain distinct, with silent incorrect success counted in published evidence.", "them": "The acting model reports task completion from what it sees; providers direct developers to keep a human in the loop for high-impact actions rather than providing an out-of-band business-effect oracle.", "sources": [ diff --git a/data/compare/playwright.json b/data/compare/playwright.json new file mode 100644 index 00000000..abe74dd1 --- /dev/null +++ b/data/compare/playwright.json @@ -0,0 +1,80 @@ +{ + "slug": "playwright", + "competitor": "Playwright", + "positioningSummary": "Playwright is the direct choice for developer-owned browser automation. OpenAdapt is for demonstrated workflows that cross GUI surfaces or need governed effect verification and explicit outcomes.", + "dimensions": [ + { + "id": "determinism-on-drift", + "label": "Determinism when interfaces drift", + "openadapt": "A compiled workflow replays from retained evidence. If the target cannot be resolved or verified, the run halts or produces a reviewable repair proposal.", + "them": "A Playwright script replays explicit code. User-facing locators and auto-waiting make ordinary page changes easier to tolerate, but a changed contract still requires code or locator maintenance.", + "sources": [ + {"label": "Playwright locators", "url": "https://playwright.dev/docs/locators"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "cost-per-run", + "label": "Cost per run", + "openadapt": "The MIT local runtime has no per-run license fee, and a healthy compiled run makes no model call.", + "them": "The Playwright library is open source. A normal script makes no model call, while browser, compute, and any grid service remain operating costs.", + "sources": [ + {"label": "Playwright repository and license", "url": "https://github.com/microsoft/playwright"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "verification-of-effects", + "label": "Verification of business effects", + "openadapt": "A consequential run can finish only after an independent verifier checks the intended effect against the system of record.", + "them": "Playwright supplies web assertions and retrying checks. The developer decides whether those assertions inspect the page, a separate API, a database, or another effect oracle.", + "sources": [ + {"label": "Playwright auto-retrying assertions", "url": "https://playwright.dev/docs/test-assertions"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "halting-behavior", + "label": "Halting behavior", + "openadapt": "Identity, target, policy, and effect checks define halt conditions. An uncertain write is preserved for reconciliation and is not retried blindly.", + "them": "Playwright waits for actionability before an action and fails an action when its checks or timeouts do not pass. Business retry and reconciliation behavior belongs to the script.", + "sources": [ + {"label": "Playwright actionability", "url": "https://playwright.dev/docs/actionability"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "data-locality", + "label": "Data locality", + "openadapt": "Recordings, compiled bundles, and run evidence can stay in a customer-controlled boundary on the MIT runtime.", + "them": "Playwright can run on local or customer-controlled machines. Data leaves that boundary only when the script or its surrounding services send it elsewhere.", + "sources": [ + {"label": "Playwright installation and local browser support", "url": "https://playwright.dev/docs/intro"}, + {"label": "OpenAdapt trust center", "url": "https://openadapt.ai/security"} + ] + }, + { + "id": "scope", + "label": "Scope: browser, desktop, RDP/Citrix", + "openadapt": "The runtime covers browser, native desktop, and customer-qualified remote-window workflows. Each exact surface remains bound to its published qualification evidence.", + "them": "Playwright automates Chromium, Firefox, and WebKit. It is a browser library, not a native desktop or remote-window automation system.", + "sources": [ + {"label": "Playwright browser support", "url": "https://playwright.dev/"}, + {"label": "OpenAdapt qualification evidence", "url": "https://docs.openadapt.ai/get-started/what-works-today/"} + ] + } + ], + "strengths": [ + {"text": "User-facing locators prioritize roles, labels, text, and test IDs instead of long CSS or XPath chains.", "source": {"label": "Playwright locators", "url": "https://playwright.dev/docs/locators"}}, + {"text": "Actionability checks wait for visibility, stability, event reception, and enabled state before common actions.", "source": {"label": "Playwright actionability", "url": "https://playwright.dev/docs/actionability"}}, + {"text": "One API supports Chromium, Firefox, and WebKit across major operating systems.", "source": {"label": "Playwright overview", "url": "https://playwright.dev/"}}, + {"text": "The project supports TypeScript, JavaScript, Python, Java, and .NET.", "source": {"label": "Playwright languages", "url": "https://playwright.dev/docs/languages"}} + ], + "faq": [ + { + "question": "Should I replace a working Playwright script with OpenAdapt?", + "answer": "Usually not. Keep a well-owned browser script when it covers the full task and its assertions prove the right result. Consider OpenAdapt when the work crosses surfaces, starts from a human demonstration, or needs a governed verification contract.", + "sources": [{"label": "OpenAdapt comparison guide", "url": "https://openadapt.ai/compare/playwright"}] + } + ] +} diff --git a/data/compare/power-automate.json b/data/compare/power-automate.json index 3b4a24db..51e66aee 100644 --- a/data/compare/power-automate.json +++ b/data/compare/power-automate.json @@ -40,7 +40,7 @@ "id": "verification-of-effects", "label": "Verification of business effects", "openadapt": - "Every consequential run ends VERIFIED or HALTED based on an out-of-band check of the system of record - REST readback, SQL, table-delta audit, or file arrival - never the acting session's own report.", + "VERIFIED requires an out-of-band check of the system of record, such as REST readback, SQL, table-delta audit, or file arrival. Refusal before effect and uncertain delivery remain separate typed outcomes.", "them": "Cloud flows surface run history and error details in the Power Platform admin center; Dataverse stores the data flows act on. Verification of a desktop flow's business effect is typically expressed as configured assertions or downstream checks the builder authors.", "sources": [ diff --git a/data/compare/selenium.json b/data/compare/selenium.json new file mode 100644 index 00000000..f8c20bdb --- /dev/null +++ b/data/compare/selenium.json @@ -0,0 +1,80 @@ +{ + "slug": "selenium", + "competitor": "Selenium", + "positioningSummary": "Selenium is the established standards-based choice for browser control. OpenAdapt adds demonstration-based compilation and a governed result contract across browser, desktop, and remote interfaces.", + "dimensions": [ + { + "id": "determinism-on-drift", + "label": "Determinism when interfaces drift", + "openadapt": "A compiled workflow replays from retained evidence, re-resolves within its contract, proposes a governed repair, or halts.", + "them": "WebDriver runs explicit commands against selected elements. Changed locators or page behavior require waits, fallback logic, or code maintenance by the owner.", + "sources": [ + {"label": "Selenium WebDriver", "url": "https://www.selenium.dev/documentation/webdriver/"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "cost-per-run", + "label": "Cost per run", + "openadapt": "The MIT local runtime has no per-run license fee, and healthy compiled replay makes no model call.", + "them": "Selenium is open source and a normal WebDriver run makes no model call. Browser fleet, grid, and maintenance costs depend on the deployment.", + "sources": [ + {"label": "Selenium project", "url": "https://www.selenium.dev/about/"}, + {"label": "OpenAdapt method", "url": "https://openadapt.ai/how-it-works"} + ] + }, + { + "id": "verification-of-effects", + "label": "Verification of business effects", + "openadapt": "An independent verifier can check the system of record before a consequential run returns VERIFIED.", + "them": "WebDriver returns browser command results. The automation author must add page assertions or a separate API, database, file, or service check for the business effect.", + "sources": [ + {"label": "Selenium WebDriver commands", "url": "https://www.selenium.dev/documentation/webdriver/"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "halting-behavior", + "label": "Halting behavior", + "openadapt": "The workflow refuses before actuation when identity, target, or policy checks fail. If delivery may have occurred but the effect cannot be proved, it returns RECONCILIATION_REQUIRED without a blind retry.", + "them": "Selenium supports explicit and implicit waits, then raises errors when conditions or commands fail. Retry, rollback, and reconciliation rules live in the surrounding test or application code.", + "sources": [ + {"label": "Selenium waits", "url": "https://www.selenium.dev/documentation/webdriver/waits/"}, + {"label": "OpenAdapt safety model", "url": "https://openadapt.ai/safety"} + ] + }, + { + "id": "data-locality", + "label": "Data locality", + "openadapt": "Recordings, compiled bundles, and run evidence can remain on customer-controlled infrastructure.", + "them": "WebDriver can run locally or through a remote endpoint. The operator controls whether screenshots and browser data stay local or travel to a grid service.", + "sources": [ + {"label": "Selenium remote WebDriver", "url": "https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/"}, + {"label": "OpenAdapt trust center", "url": "https://openadapt.ai/security"} + ] + }, + { + "id": "scope", + "label": "Scope: browser, desktop, RDP/Citrix", + "openadapt": "The runtime covers browser, native desktop, and customer-qualified remote-window workflows, subject to the exact published qualification evidence.", + "them": "Selenium WebDriver drives major browsers locally or remotely. It does not provide native desktop or remote-window GUI automation.", + "sources": [ + {"label": "Selenium WebDriver", "url": "https://www.selenium.dev/documentation/webdriver/"}, + {"label": "OpenAdapt qualification evidence", "url": "https://docs.openadapt.ai/get-started/what-works-today/"} + ] + } + ], + "strengths": [ + {"text": "WebDriver became a W3C Recommendation for remote browser control in 2018.", "source": {"label": "W3C WebDriver Recommendation", "url": "https://www.w3.org/TR/2018/REC-webdriver1-20180605/"}}, + {"text": "Selenium supports local and remote browser sessions, including distributed Grid deployments.", "source": {"label": "Selenium Grid", "url": "https://www.selenium.dev/documentation/grid/"}}, + {"text": "The project publishes language bindings for Java, Python, C#, Ruby, JavaScript, and Kotlin.", "source": {"label": "Selenium downloads", "url": "https://www.selenium.dev/downloads/"}}, + {"text": "Established teams can keep their existing tests, infrastructure, and maintenance practices.", "source": null} + ], + "faq": [ + { + "question": "Is OpenAdapt a Selenium replacement?", + "answer": "No. Selenium remains a strong browser-control layer. OpenAdapt addresses a broader workflow contract: demonstration-based authoring, cross-surface replay, independent effect verification, and explicit halt behavior.", + "sources": [{"label": "OpenAdapt comparison guide", "url": "https://openadapt.ai/compare/selenium"}] + } + ] +} diff --git a/data/compare/uipath.json b/data/compare/uipath.json index 730be7ef..330c2de2 100644 --- a/data/compare/uipath.json +++ b/data/compare/uipath.json @@ -40,7 +40,7 @@ "id": "verification-of-effects", "label": "Verification of business effects", "openadapt": - "Success is established out of band - read-only API reads, SQL queries, table-delta audits, or file checks against the system of record - and every run ends VERIFIED or HALTED with preserved evidence.", + "Success is established out of band through read-only API reads, SQL queries, table-delta audits, or file checks. VERIFIED, refusal before effect, and RECONCILIATION_REQUIRED after uncertain delivery remain distinct outcomes with preserved evidence.", "them": "Orchestrator provides centralized audit trails, search, filter, and export of audit events, and queue-based transaction status. The acting session's own success signals remain the primary in-band check; an independent read-back of the business system of record is not part of the published core loop.", "sources": [ diff --git a/data/comparisons.js b/data/comparisons.js index c5882c51..e4c2f59e 100644 --- a/data/comparisons.js +++ b/data/comparisons.js @@ -19,7 +19,7 @@ export const OPENADAPT_DIFFERENTIATORS = [ }, { title: 'Explicit transaction outcomes', - body: 'Every consequential run ends verified or halted with a preserved run report. There is no silent third state where the workflow looked finished but the record never changed.', + body: 'Every consequential run ends with a typed outcome and a preserved run report. VERIFIED requires independent proof. A refusal before actuation and uncertain delivery after possible actuation remain distinct, so an unconfirmed write cannot appear as success.', }, { title: 'Deterministic healthy runs', @@ -70,6 +70,7 @@ export const COMPARISONS = [ 'Choose OpenAdapt when the workflows that matter are consequential transactions where you need the system of record independently confirmed after every run, when sensitive data must stay in your boundary on an inspectable MIT runtime, or when you want a zero-install lane into managed remote estates.', honestNote: 'Recording a demonstration, visual targeting, and repairing broken selectors are not differentiators in either direction: modern RPA platforms and OpenAdapt all do these. The difference is how a run is judged and what a failure is allowed to look like.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-uipath/', }, { slug: 'power-automate', @@ -91,9 +92,10 @@ export const COMPARISONS = [ chooseThem: 'Choose Power Automate when the work lives inside the Microsoft ecosystem, when a supported connector already reaches the system you need, or when low per-seat cost across many light automations matters more than transaction-level verification.', chooseUs: - 'Choose OpenAdapt when the last mile is a non-Microsoft or legacy GUI, when a wrong write is expensive enough that you need the business effect independently verified out of band, when runs must end in an explicit verified-or-halted outcome, or when the runtime must be open, local, and customer-controlled.', + 'Choose OpenAdapt when the last mile is a non-Microsoft or legacy GUI, when a wrong write is expensive enough that you need the business effect independently verified out of band, when every run needs a typed transaction outcome, or when the runtime must be open, local, and customer-controlled.', honestNote: 'If a supported connector or API completes the workflow reliably, use it. OpenAdapt exists for the UI-only remainder where no practical API exists and correctness has to be proved, not assumed.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-power-automate/', }, { slug: 'computer-use-agents', @@ -114,9 +116,10 @@ export const COMPARISONS = [ chooseThem: 'Choose a computer-use agent for exploratory, novel, or constantly changing work, for research and triage, or for tasks you will run a handful of times and never again.', chooseUs: - 'Choose OpenAdapt when the same consequential workflow repeats: healthy runs are deterministic with zero model calls and zero per-run token cost, every run ends verified or halted against an independent check of the system of record, and the runtime is MIT-licensed and can execute entirely inside your boundary.', + 'Choose OpenAdapt when the same consequential workflow repeats: healthy runs are deterministic with zero model calls and zero per-run token cost, VERIFIED requires an independent check of the system of record, uncertain delivery has its own reconciliation outcome, and the runtime is MIT-licensed and can execute entirely inside your boundary.', honestNote: 'These approaches are complementary rather than rivals: agent providers themselves recommend human oversight for consequential actions, and OpenAdapt uses models too, at compile and repair time rather than on every healthy run. The question is whether each run should re-reason the task or replay a verified program.', + blogUrl: 'https://blog.openadapt.ai/posts/the-500th-run/', }, { slug: 'record-and-replay', @@ -139,7 +142,7 @@ export const COMPARISONS = [ chooseUs: 'Choose OpenAdapt when a replayed action writes to a system of record that matters: the compiled program is reviewable, healthy runs are deterministic with zero model calls, the business effect is verified out of band after the run, ambiguity halts instead of guessing, and the MIT runtime plus your data can stay entirely inside your boundary.', honestNote: - 'Recording is the commodity; OpenAdapt does not claim to record better. The difference is governance: an independent verifier, an explicit verified-or-halted outcome for every run, and published qualification evidence per execution surface.', + 'Recording is the commodity; OpenAdapt does not claim to record better. The difference is governance: an independent verifier, typed transaction outcomes that preserve uncertainty, and published qualification evidence per execution surface.', }, { slug: 'browser-agents', @@ -160,7 +163,7 @@ export const COMPARISONS = [ chooseThem: 'Choose a browser-agent platform for web-only, read-heavy, or exploratory automation, for prototypes, and for workloads where a failed or repeated attempt has little cost.', chooseUs: - 'Choose OpenAdapt when the workflow also crosses desktop or remote surfaces, when the acting session must not be the judge of its own success, when every consequential run needs an explicit verified-or-halted outcome, or when sensitive data cannot transit a vendor cloud and must run on a customer-controlled MIT runtime.', + 'Choose OpenAdapt when the workflow also crosses desktop or remote surfaces, when the acting session must not be the judge of its own success, when every consequential run needs a typed outcome that preserves uncertainty, or when sensitive data cannot transit a vendor cloud and must run on a customer-controlled MIT runtime.', honestNote: 'Most browser-agent stacks judge success in-band: the same session that acted decides whether it worked. OpenAdapt verifies the business effect out of band, against the system of record, after the run.', }, @@ -183,10 +186,106 @@ export const COMPARISONS = [ chooseThem: 'Keep a hand-rolled script when it already works, a developer owns and maintains it, and its failure modes are understood and affordable.', chooseUs: - 'Choose OpenAdapt when scripts have become an unowned maintenance burden, when non-developers need to author workflows by demonstration, or when you need what scripts rarely include: independent out-of-band verification of the business effect, an explicit verified-or-halted outcome with a preserved run report, and halts on ambiguity instead of best-effort clicks. The runtime is MIT-licensed, so you trade none of the openness.', + 'Choose OpenAdapt when scripts have become an unowned maintenance burden, when non-developers need to author workflows by demonstration, or when you need what scripts rarely include: independent out-of-band verification, typed outcomes for refusal and uncertain delivery, and a preserved run report. The runtime is MIT-licensed, so you trade none of the openness.', honestNote: 'OpenAdapt does not claim your script cannot work. It packages the verification, outcome discipline, and audit trail that consequential scripts eventually grow by hand, and it publishes qualification evidence per surface instead of assuming coverage.', }, + { + slug: 'playwright', + name: 'Playwright', + title: 'OpenAdapt vs Playwright', + metaDescription: + 'Use Playwright for direct, developer-owned browser automation. Use OpenAdapt when a demonstrated workflow crosses surfaces or needs governed effect verification.', + intro: 'Playwright is an excellent browser automation library. Its locators, actionability checks, auto-waiting, tracing, and cross-browser support make it the first tool we would reach for when a developer owns a web-only workflow. OpenAdapt compiles a person’s demonstration into governed replay across browser, desktop, and remote applications.', + theirStrengths: { + heading: 'Where Playwright is strong', + items: [ + 'First-class browser automation across Chromium, Firefox, and WebKit.', + 'User-facing locators and automatic actionability checks reduce brittle waits and selectors.', + 'Precise control in TypeScript, JavaScript, Python, Java, and .NET, with a strong test runner and trace viewer.', + 'A small Playwright script is often the clearest answer when a developer owns one stable web workflow.', + ], + }, + chooseThem: + 'Choose Playwright when the workflow is browser-only, a developer can maintain the code, DOM access is available, and normal assertions can prove the result.', + chooseUs: + 'Choose OpenAdapt when the workflow starts with a human demonstration, crosses browser and desktop surfaces, runs outside the page DOM, or needs typed transaction outcomes backed by an independent effect check.', + honestNote: + 'OpenAdapt uses Playwright where browser-native identity is useful. Playwright can remain part of the OpenAdapt execution path.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-playwright/', + }, + { + slug: 'selenium', + name: 'Selenium', + title: 'OpenAdapt vs Selenium', + metaDescription: + 'Use Selenium for standards-based browser control and established test fleets. Use OpenAdapt for demonstrated, governed workflows across GUI surfaces.', + intro: 'Selenium WebDriver is the durable standard for controlling browsers locally or on remote machines. It has broad language support, a large ecosystem, and years of production use. OpenAdapt does not replace that browser-control layer. It adds demonstration-based compilation, cross-surface execution, and a governed result contract for repeated business work.', + theirStrengths: { + heading: 'Where Selenium is strong', + items: [ + 'A W3C-standard browser-control protocol supported by all major browsers.', + 'Remote WebDriver and Grid support for distributed browser fleets.', + 'Language bindings and a large ecosystem built over many years.', + 'A good fit for organizations with established Selenium tests, infrastructure, and maintainers.', + ], + }, + chooseThem: + 'Choose Selenium when you need standards-based browser control, already operate a Selenium fleet, or want explicit code and assertions for a web-only workflow.', + chooseUs: + 'Choose OpenAdapt when the job must be authored by demonstration, continue into desktop or remote applications, or finish only after an independent verifier proves the intended business effect.', + honestNote: + 'A well-owned Selenium workflow should stay in place. OpenAdapt earns its keep when the work is broader than browser control or the missing parts are qualification, effect verification, and safe halting.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-selenium/', + }, + { + slug: 'autohotkey', + name: 'AutoHotkey', + title: 'OpenAdapt vs AutoHotkey', + metaDescription: + 'Use AutoHotkey for fast personal Windows macros and hotkeys. Use OpenAdapt for governed, reviewable workflows with independent effect verification.', + intro: 'AutoHotkey is hard to beat for a quick Windows macro. A short script can send keys, click controls, remap input, and remove hours of personal repetition with almost no ceremony. OpenAdapt is for the point where that macro becomes shared operational software and a wrong result matters.', + theirStrengths: { + heading: 'Where AutoHotkey is strong', + items: [ + 'Fast Windows hotkeys, text expansion, remapping, and desktop macros in small scripts.', + 'Direct control over keys, mouse input, windows, and many native controls.', + 'No service dependency and no model call is required to run a normal script.', + 'A very good fit for personal automation where the author is also the operator and maintainer.', + ], + }, + chooseThem: + 'Choose AutoHotkey for a personal Windows shortcut, a compact macro, or a stable task whose occasional failure is easy for the operator to see and correct.', + chooseUs: + 'Choose OpenAdapt when several people rely on the workflow, authoring must begin with a demonstration, the target can drift, or every consequential run must end with preserved evidence and a typed transaction result.', + honestNote: + 'AutoHotkey is open, local, deterministic, and cheap. OpenAdapt does not improve those traits. It adds a compiler, retained visual evidence, reviewable repair, qualification, and independent effect checks.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-autohotkey/', + }, + { + slug: 'api', + name: 'a supported API', + title: 'OpenAdapt vs a direct API', + metaDescription: + 'Use a supported API whenever it reaches the required business operation. Use OpenAdapt for the UI-only remainder and verify the effect independently.', + intro: 'A supported API is usually the best automation interface. It is direct, testable, and easier to operate than a GUI. OpenAdapt is not an argument against APIs. It handles the last mile when the required operation exists only behind a browser, desktop application, RDP session, or Citrix window.', + theirStrengths: { + heading: 'Where a direct API is strong', + items: [ + 'It calls the system directly without rendering or manipulating an interface.', + 'Requests, responses, authentication, versioning, and error handling can be tested in code.', + 'It usually runs faster and with less infrastructure than GUI automation.', + 'The service owner can publish a stable contract and support it as the product changes.', + ], + }, + chooseThem: + 'Choose the API when it exposes the complete operation you need, its use is permitted, and you can verify the resulting record through the same or a separate read-only interface.', + chooseUs: + 'Choose OpenAdapt for the exact steps the API does not expose, including legacy, desktop, remote, and vendor-controlled interfaces. Keep API calls for the parts they can do, including independent verification after GUI actuation.', + honestNote: + 'Use APIs for data movement, orchestration, and verification. Limit OpenAdapt actuation to the UI-bound transaction that the API does not expose.', + blogUrl: 'https://blog.openadapt.ai/posts/openadapt-vs-api/', + }, ] export const COMPARISON_LINKS = COMPARISONS.map(({ slug, name, title }) => ({ diff --git a/pages/compare.js b/pages/compare.js index 0c8d6704..c42c80b6 100644 --- a/pages/compare.js +++ b/pages/compare.js @@ -178,6 +178,18 @@ export default function ComparePage() { > See measured results + + track(EVENTS.COMPARE_CTA_CLICK, { + cta: 'gui_automation_guide', + location: 'compare_hero', + }) + } + > + Read the practical guide +
diff --git a/pages/compare/[slug].js b/pages/compare/[slug].js index 44b7c557..e936c227 100644 --- a/pages/compare/[slug].js +++ b/pages/compare/[slug].js @@ -30,14 +30,8 @@ export async function getStaticPaths() { export async function getStaticProps({ params }) { const comparison = COMPARISONS.find(({ slug }) => slug === params.slug) - let dimensionData = null - try { - const structured = loadComparisons('data/compare') - dimensionData = findComparison(structured, params.slug) - } catch (error) { - if (process.env.NODE_ENV !== 'production') throw error - dimensionData = null - } + const structured = loadComparisons('data/compare') + const dimensionData = findComparison(structured, params.slug) return { props: { comparison, dimensionData } } } @@ -153,6 +147,17 @@ export default function ComparisonDetailPage({ comparison, dimensionData }) {

{comparison.intro}

+ {comparison.blogUrl && ( +

+ The blog examines the operating tradeoffs in more detail.{' '} + + Read the comparison article. + +

+ )} {/* Capability dimensions, generated from data/compare/.json */} {dimensionData && ( @@ -383,8 +388,9 @@ export default function ComparisonDetailPage({ comparison, dimensionData }) { Bring one repeated, consequential workflow and measure authoring time, run time, intervention rate, and incorrect-success rate against your current approach. - Or watch the governed-execution demo first: every run - shown ends verified or halted. + Or watch the governed-execution demo first. It shows + result checks and safe stops against the retained event + evidence.

diff --git a/pages/guides/automate-repetitive-gui-tasks.js b/pages/guides/automate-repetitive-gui-tasks.js new file mode 100644 index 00000000..a2e1015b --- /dev/null +++ b/pages/guides/automate-repetitive-gui-tasks.js @@ -0,0 +1,228 @@ +import Head from 'next/head' +import Link from 'next/link' + +import Footer from '@components/Footer' +import { track, EVENTS } from 'utils/analytics' + +const url = 'https://openadapt.ai/guides/automate-repetitive-gui-tasks' +const description = + 'A practical guide to automating repetitive GUI tasks with APIs, Playwright, Selenium, AutoHotkey, Power Automate, UiPath, computer-use agents, or OpenAdapt.' + +const approaches = [ + { + name: 'OpenAdapt', + fit: 'The same consequential GUI workflow repeats, no practical API covers it, and another interface can verify the result.', + reason: 'You demonstrate the task once. OpenAdapt compiles it into deterministic local replay, then re-resolves, proposes a governed repair, or halts under drift.', + href: '/how-it-works', + linkLabel: 'See how OpenAdapt works', + }, + { + name: 'A supported API', + fit: 'The application exposes the complete operation through a supported machine interface.', + reason: 'It skips the screen. That usually makes the workflow faster, easier to test, and cheaper to run.', + href: '/compare/api', + linkLabel: 'Compare OpenAdapt with an API', + }, + { + name: 'Playwright', + fit: 'The task is browser-only, and a developer can own the script.', + reason: 'Its locators, auto-waiting, tracing, and cross-browser support make web automation pleasant to maintain.', + href: '/compare/playwright', + linkLabel: 'Compare OpenAdapt with Playwright', + }, + { + name: 'Selenium', + fit: 'You need standards-based browser control or already run a Selenium fleet.', + reason: 'WebDriver has broad browser, language, and remote-grid support, plus a large mature ecosystem.', + href: '/compare/selenium', + linkLabel: 'Compare OpenAdapt with Selenium', + }, + { + name: 'AutoHotkey', + fit: 'One person needs a fast Windows shortcut, hotkey, text expansion, or small macro.', + reason: 'A short local script can remove personal repetition with very little setup.', + href: '/compare/autohotkey', + linkLabel: 'Compare OpenAdapt with AutoHotkey', + }, + { + name: 'Microsoft Power Automate', + fit: 'The work sits inside Microsoft 365, Dataverse, Teams, Excel, or a supported connector.', + reason: 'It joins cloud flows, desktop automation, connectors, identity, and administration in the Microsoft stack.', + href: '/compare/power-automate', + linkLabel: 'Compare OpenAdapt with Power Automate', + }, + { + name: 'UiPath', + fit: 'You need an enterprise RPA platform for a large robot fleet and an established automation program.', + reason: 'Its orchestration, queues, credentials, audit tools, training, partners, and activity ecosystem are mature.', + href: '/compare/uipath', + linkLabel: 'Compare OpenAdapt with UiPath', + }, + { + name: 'A computer-use agent', + fit: 'The task is novel, exploratory, or changes so often that you want a model to reason through each run.', + reason: 'It can start from a plain-language goal and work through unfamiliar interfaces without a recorded workflow.', + href: '/compare/computer-use-agents', + linkLabel: 'Compare OpenAdapt with computer-use agents', + }, +] + +const faq = [ + { + question: 'What is the best tool for automating repetitive GUI tasks?', + answer: 'OpenAdapt fits repeated GUI transactions that need deterministic replay and an independent effect check. Use a supported API when it covers the complete operation. Playwright or Selenium fits developer-owned browser work, AutoHotkey fits a personal Windows macro, Power Automate fits Microsoft-centric work, UiPath fits an enterprise RPA program, and a computer-use agent fits novel tasks.', + }, + { + question: 'How do I automate a GUI application with no API?', + answer: 'Define one bounded task, record or script it, separate inputs from recorded examples, add identity and effect checks, test normal and changed interfaces, then deploy it inside the correct data boundary. OpenAdapt packages that path around a demonstration.', + }, + { + question: 'How do I automate a Citrix or RDP application?', + answer: 'Treat the remote session as a visible window. Keep capture and actuation outside the managed environment when you cannot install inside it. Use fresh frames, visual and OCR evidence, window identity, and an independent effect check. Qualify the exact client, application, display, and workflow before consequential use.', + }, + { + question: 'Can I turn a screen recording into automation?', + answer: 'Yes, but a video alone is not enough for a dependable transaction. The useful artifact also needs action timing, target evidence, inputs, postconditions, and a rule for what to do when the live interface no longer matches the demonstration.', + }, +] + +const faqSchema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + mainEntity: faq.map((item) => ({ + '@type': 'Question', + name: item.question, + acceptedAnswer: { '@type': 'Answer', text: item.answer }, + })), +} + +const howToSchema = { + '@context': 'https://schema.org', + '@type': 'HowTo', + name: 'How to automate a repetitive GUI task', + description, + step: [ + { '@type': 'HowToStep', name: 'Bound the task', text: 'Name one start state, one intended result, and the allowed applications.' }, + { '@type': 'HowToStep', name: 'Check for an API', text: 'Use a supported API or connector wherever it covers the required operation.' }, + { '@type': 'HowToStep', name: 'Choose the GUI tool', text: 'Match the tool to the browser, desktop, remote, personal, or enterprise operating boundary.' }, + { '@type': 'HowToStep', name: 'Add a separate result check', text: 'Verify the effect through a read-only API, database query, file check, or independent screen state.' }, + { '@type': 'HowToStep', name: 'Test change and uncertainty', text: 'Test normal runs, interface drift, wrong identity, ambiguous targets, and uncertain delivery.' }, + ], +} + +export default function AutomateRepetitiveGuiTasksPage() { + return ( +
+ + How to automate repetitive GUI tasks | OpenAdapt + + + + + +