Navigate the AWS Console via browser or Playwright MCP — SSO authentication, account selection, region switching, CloudWatch Logs Insights, alarms, metrics. Covers iframe DOM patterns for screenshot capture: scroll, row click, element interaction inside the microConsole iframe. Keywords: Playwright SSO iframe CloudWatch browser-automation screenshot microConsole logs-table__wrapper page.mouse.click frame.evaluate IAM-Identity-Center region cookie-banner sidebar-collapse locator-timeout.
64
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./skills/infrastructure/aws/investigation-toolkit/skills/aws-console-navigator/SKILL.mdThe CloudWatch console is a micro-frontend SPA embedded inside an iframe
(iframe[name="microConsole-Logs"]). This has three non-obvious consequences:
window.document is the outer shell, not CloudWatch. All DOM queries must target
the iframe's contentDocument. In Playwright, use page.frame({ name: 'microConsole-Logs' }).
locator.click() on iframe elements times out. Playwright's locator API hits a 5 s
timeout when clicking elements inside cross-origin iframes. Use page.mouse.click(x, y)
with coordinates calculated from the iframe bounding box + element's getBoundingClientRect.
The results table is its own scroll container. window.scrollBy() scrolls the outer
shell. The CloudWatch results table lives in DIV.logs-table__wrapper. Scroll it directly:
frame.evaluate(() => document.querySelector('.logs-table__wrapper').scrollTop = N).
locator.click() works normally thereaws-cloudwatch-url-builder insteadDirect URL: See aws-cloudwatch-url-builder for the encoded URL template.
Direct URL:
https://{region}.console.aws.amazon.com/cloudwatch/home?region={region}#alarmsV2:alarm/{alarm_name}For full SSO auth steps and region codes, see references/console-reference.md.
Full Playwright code snippets are in references/playwright-patterns.md.
Get the frame reference first — optionally cache it for reuse across multiple operations:
const frame = page.frame({ name: 'microConsole-Logs' });
await page.waitForSelector('iframe[name="microConsole-Logs"]', { timeout: 15000 });Scroll the results table (use frame.evaluate, not window.scrollBy):
await frame.evaluate(() => {
document.querySelector('.logs-table__wrapper').scrollTop = 600;
});Expand a log row using page-level coordinates (consider pre-calculating for multiple rows):
const iframeBox = await page.locator('iframe[name="microConsole-Logs"]').boundingBox();
const rowBox = await frame.locator('tr.logs-table__row').first().boundingBox();
await page.mouse.click(iframeBox.x + rowBox.x + 20, iframeBox.y + rowBox.y + rowBox.height / 2);Each entry shows the BAD practice and the GOOD replacement.
❌ NEVER use locator.click() directly on CloudWatch iframe elements
WHY: Playwright's locator.click() uses accessibility tree traversal and times out after 5 s
when targeting elements inside a cross-origin or sandboxed iframe.
✅ BAD: await frame.locator('tr').first().click() → GOOD: calculate page-level coordinates
from iframeBox + rowBox, then call page.mouse.click(absoluteX, absoluteY).
❌ NEVER use window.scrollBy() or window.scrollTo() inside the CloudWatch iframe
WHY: window in the iframe context scrolls MAIN.logs__main__visual-refresh (the outer
page-level scroller), not the results table. The results table is in a separate overflow
container (DIV.logs-table__wrapper) and will not move.
✅ Use: frame.evaluate(() => document.querySelector('.logs-table__wrapper').scrollTop = N)
❌ NEVER query window.document from page.evaluate() to interact with CloudWatch content
WHY: page.evaluate() runs in the outer shell document. CloudWatch content is inside the iframe.
document.querySelector('.logs-table__wrapper') returns null from page.evaluate().
✅ Use frame.evaluate() where frame = page.frame({ name: 'microConsole-Logs' }).
❌ NEVER assume AWS/Lambda Errors = 0 means no alarm triggered
WHY: The native AWS/Lambda Errors metric counts invocation-level failures (exit code ≠ 0).
An alarm driven by a Logs metric filter fires even when the invocation exits cleanly, as
long as ERROR-level log lines were emitted.
✅ Always screenshot the alarm detail page, not the raw AWS/Lambda Errors metric graph.
a1083f4
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.