From 7e4d9c2b5e0c29a9d863c9c8f8831264a90bae81 Mon Sep 17 00:00:00 2001 From: adminvns Date: Wed, 15 Jul 2026 00:38:25 +0530 Subject: [PATCH] added seo changes and blogs -fixed light mode --- assets/css/style.css | 390 +++++++++++++++++- ...al-llm-testing-guide-for-qa-engineers.html | 265 ++++++++++++ ...eval-llm-testing-guide-for-qa-engineers.md | 88 ++++ ...ewright-playwright-for-mobile-testing.html | 246 +++++++++++ ...ilewright-playwright-for-mobile-testing.md | 72 ++++ .../playwright-mcp-ai-browser-automation.html | 244 +++++++++++ blog/playwright-mcp-ai-browser-automation.md | 72 ++++ index.html | 277 +++++++++++-- inner-page.html | 133 ------ portfolio-details.html | 172 -------- robots.txt | 54 +++ sitemap.xml | 18 +- 12 files changed, 1668 insertions(+), 363 deletions(-) create mode 100644 blog/deepeval-llm-testing-guide-for-qa-engineers.html create mode 100644 blog/deepeval-llm-testing-guide-for-qa-engineers.md create mode 100644 blog/mobilewright-playwright-for-mobile-testing.html create mode 100644 blog/mobilewright-playwright-for-mobile-testing.md create mode 100644 blog/playwright-mcp-ai-browser-automation.html create mode 100644 blog/playwright-mcp-ai-browser-automation.md delete mode 100644 inner-page.html delete mode 100644 portfolio-details.html diff --git a/assets/css/style.css b/assets/css/style.css index c0135e5..fe1afe8 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -20,7 +20,8 @@ --glass-bg: rgba(32, 52, 159, 0.05); --glass-border: rgba(32, 52, 159, 0.1); --heading-color: #20349F; - --header-bg: #040b14; + --header-bg: #eef1f8; + --header-border: rgba(32, 52, 159, 0.12); } body.dark-mode { @@ -33,6 +34,8 @@ body.dark-mode { --glass-bg: rgba(255, 255, 255, 0.05); --glass-border: rgba(255, 255, 255, 0.1); --heading-color: #ffffff; + --header-bg: #040b14; + --header-border: rgba(255, 255, 255, 0.08); } body { @@ -111,6 +114,7 @@ h6 { transition: all 0.5s; padding: 0 15px; background: var(--header-bg); + border-right: 1px solid var(--header-border); overflow-y: auto; } @@ -142,7 +146,7 @@ h6 { font-size: 18px; display: inline-block; background: var(--glass-bg); - color: #fff; + color: var(--heading-color); line-height: 1; padding: 8px 0; margin-right: 4px; @@ -267,7 +271,7 @@ h6 { .nav-menu a:focus { display: flex; align-items: center; - color: #a8a9b4; + color: var(--text-muted); padding: 12px 15px; margin-bottom: 8px; transition: 0.3s; @@ -278,7 +282,7 @@ h6 { .nav-menu a:focus i { font-size: 24px; padding-right: 8px; - color: #6f7180; + color: var(--text-muted); } .nav-menu a:hover, @@ -286,7 +290,7 @@ h6 { .nav-menu .active:focus, .nav-menu li:hover>a { text-decoration: none; - color: #fff; + color: var(--heading-color); } .nav-menu a:hover i, @@ -377,12 +381,13 @@ h6 { min-width: 300px; } -#hero h1 { +#hero h1, +#hero h2 { margin: 0 0 10px 0; font-size: 80px; font-weight: 800; line-height: 1.1; - background: linear-gradient(to right, #ffffff, var(--accent-primary)); + background: linear-gradient(to right, #ffffff, #6c7dff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; /* Hero text always white-ish for visibility */ @@ -1432,7 +1437,7 @@ section { --------------------------------------------------------------*/ #footer { padding: 15px; - color: #eaebf0; + color: var(--text-main); font-size: 14px; position: fixed; left: 0; @@ -1440,6 +1445,7 @@ section { width: 300px; z-index: 9999; background: var(--header-bg); + border-right: 1px solid var(--header-border); } #footer .copyright { @@ -1466,6 +1472,7 @@ section { background: var(--primary-bg); color: var(--text-muted); border-top: 1px solid var(--glass-border); + border-right: none; } } @@ -1846,6 +1853,32 @@ input:checked+.slider:before { transform: scale(1.1) rotate(5deg); } +/* Brand chip for logos that need a background to stay legible (e.g. Tricentis navy) */ +.skill-logo-chip { + width: 60px; + height: 60px; + border-radius: 12px; + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto 15px; + transition: transform 0.3s ease; +} + +.skill-logo-chip img { + width: 62%; + height: 62%; + object-fit: contain; +} + +.skill-card:hover .skill-logo-chip { + transform: scale(1.1) rotate(5deg); +} + +.tricentis-chip { + background: #12438c; +} + .skill-card h4 { font-size: 16px; font-weight: 600; @@ -1879,6 +1912,11 @@ input:checked+.slider:before { color: #fff; } +.skill-badge.basic { + background: linear-gradient(135deg, #8e9eab, #5f6b78); + color: #fff; +} + /* Mobile Responsiveness for Skills */ @media (max-width: 768px) { .skills-grid { @@ -2070,8 +2108,11 @@ input:checked+.slider:before { /* Text-based Tosca Logo */ .skill-logo-text { - width: 60px; + min-width: 60px; + width: fit-content; + max-width: 100%; height: 60px; + box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; @@ -2080,6 +2121,11 @@ input:checked+.slider:before { transition: transform 0.3s ease; } +.skill-logo-text .logo-brand, +.skill-logo-text .logo-product { + white-space: nowrap; +} + .skill-card:hover .skill-logo-text { transform: scale(1.1) rotate(5deg); } @@ -2136,4 +2182,330 @@ input:checked+.slider:before { .tosca-logo .logo-product { font-size: 13px; } +} + +/*-------------------------------------------------------------- +# Blog (homepage section) +--------------------------------------------------------------*/ +.blog .blog-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 25px; +} + +.blog .blog-card { + display: flex; + flex-direction: column; + background: var(--glass-bg); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid var(--glass-border); + border-radius: 15px; + padding: 28px 26px; + text-decoration: none; + color: var(--text-main); + transition: all 0.3s ease; + position: relative; + overflow: hidden; +} + +.blog .blog-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 3px; + background: linear-gradient(90deg, var(--accent-primary), transparent); + transform: scaleX(0); + transform-origin: left; + transition: transform 0.3s ease; +} + +.blog .blog-card:hover::before { + transform: scaleX(1); +} + +.blog .blog-card:hover { + transform: translateY(-8px); + border-color: var(--accent-primary); + box-shadow: 0 15px 40px rgba(32, 52, 159, 0.25); +} + +.blog .blog-card .blog-tag { + display: inline-block; + align-self: flex-start; + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + padding: 4px 12px; + border-radius: 20px; + background: linear-gradient(135deg, var(--accent-primary), var(--accent-hover)); + color: #fff; + margin-bottom: 16px; +} + +.blog .blog-card h3 { + font-size: 20px; + font-weight: 700; + line-height: 1.35; + color: var(--heading-color); + margin: 0 0 12px 0; +} + +.blog .blog-card p { + font-size: 14.5px; + line-height: 1.6; + color: var(--text-muted); + margin: 0 0 20px 0; + flex-grow: 1; +} + +.blog .blog-card .blog-meta { + font-size: 12.5px; + color: var(--text-muted); + margin-bottom: 14px; +} + +.blog .blog-card .read-more { + font-weight: 600; + color: var(--accent-primary); + display: inline-flex; + align-items: center; + gap: 6px; +} + +.blog .blog-card:hover .read-more { + gap: 12px; +} + +/*-------------------------------------------------------------- +# Blog Post (article pages under /blog/) +--------------------------------------------------------------*/ +body.blog-page { + background: var(--primary-bg); + color: var(--text-main); +} + +.blog-topbar { + position: sticky; + top: 0; + z-index: 1000; + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 24px; + background: var(--header-bg); + border-bottom: 1px solid var(--header-border); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} + +.blog-topbar a.brand { + font-weight: 700; + font-size: 18px; + color: var(--accent-primary); + text-decoration: none; + letter-spacing: 0.5px; +} + +.blog-topbar .topbar-links { + display: flex; + align-items: center; + gap: 22px; +} + +.blog-topbar .topbar-links a { + color: var(--text-muted); + text-decoration: none; + font-size: 14px; + font-weight: 500; + transition: 0.3s; +} + +.blog-topbar .topbar-links a:hover { + color: var(--accent-primary); +} + +.blog-article { + max-width: 760px; + margin: 0 auto; + padding: 40px 22px 90px; +} + +.blog-article .breadcrumb { + font-size: 13px; + color: var(--text-muted); + margin-bottom: 26px; +} + +.blog-article .breadcrumb a { + color: var(--text-muted); + text-decoration: none; +} + +.blog-article .breadcrumb a:hover { + color: var(--accent-primary); +} + +.blog-article .post-tag { + display: inline-block; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + padding: 5px 14px; + border-radius: 20px; + background: linear-gradient(135deg, var(--accent-primary), var(--accent-hover)); + color: #fff; + margin-bottom: 18px; +} + +.blog-article h1 { + font-size: clamp(28px, 5vw, 42px); + font-weight: 800; + line-height: 1.15; + color: var(--heading-color); + margin: 0 0 18px 0; +} + +.blog-article .post-meta { + font-size: 14px; + color: var(--text-muted); + margin-bottom: 34px; + padding-bottom: 24px; + border-bottom: 1px solid var(--glass-border); +} + +.blog-article h2 { + font-size: 26px; + font-weight: 700; + color: var(--heading-color); + margin: 44px 0 16px; +} + +.blog-article h3 { + font-size: 20px; + font-weight: 700; + color: var(--heading-color); + margin: 32px 0 12px; +} + +.blog-article p, +.blog-article li { + font-size: 17px; + line-height: 1.75; + color: var(--text-main); +} + +.blog-article p { + margin: 0 0 20px; +} + +.blog-article ul, +.blog-article ol { + margin: 0 0 22px; + padding-left: 24px; +} + +.blog-article li { + margin-bottom: 10px; +} + +.blog-article a { + color: var(--accent-primary); + text-decoration: underline; + text-underline-offset: 3px; +} + +.blog-article strong { + color: var(--heading-color); +} + +.blog-article blockquote { + margin: 28px 0; + padding: 16px 24px; + border-left: 4px solid var(--accent-primary); + background: var(--glass-bg); + border-radius: 0 10px 10px 0; + font-style: italic; + color: var(--text-muted); +} + +.blog-article code { + font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; + font-size: 0.88em; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + border-radius: 5px; + padding: 2px 6px; +} + +.blog-article pre { + background: #0d1424; + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 12px; + padding: 20px 22px; + overflow-x: auto; + margin: 0 0 26px; +} + +.blog-article pre code { + background: none; + border: none; + padding: 0; + color: #e6e8f0; + font-size: 14px; + line-height: 1.6; +} + +.blog-article .post-cta { + margin-top: 50px; + padding: 28px; + border-radius: 15px; + background: var(--glass-bg); + border: 1px solid var(--glass-border); + text-align: center; +} + +.blog-article .post-cta h3 { + margin-top: 0; +} + +.blog-article .post-cta a.cta-btn { + display: inline-block; + margin-top: 8px; + padding: 12px 26px; + border-radius: 30px; + background: linear-gradient(135deg, var(--accent-primary), var(--accent-hover)); + color: #fff; + text-decoration: none; + font-weight: 600; +} + +/* Blog pages have no fixed sidebar, so the footer must be static & full-width */ +body.blog-page #footer { + position: static; + width: auto; + background: var(--header-bg); + border-right: none; + border-top: 1px solid var(--header-border); + padding: 26px 15px; + color: var(--text-muted); +} + +body.blog-page #footer .credits a, +body.blog-page #footer .copyright span { + color: var(--accent-primary); +} + +@media (max-width: 575px) { + .blog-topbar .topbar-links { + gap: 14px; + } + + .blog-topbar .topbar-links a.hide-sm { + display: none; + } } \ No newline at end of file diff --git a/blog/deepeval-llm-testing-guide-for-qa-engineers.html b/blog/deepeval-llm-testing-guide-for-qa-engineers.html new file mode 100644 index 0000000..163adb4 --- /dev/null +++ b/blog/deepeval-llm-testing-guide-for-qa-engineers.html @@ -0,0 +1,265 @@ + + + + + + + + DeepEval: LLM Testing for QA Engineers (2026 Guide) | Shubham Singh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +

DeepEval: LLM Testing for QA Engineers (A Practical 2026 Guide)

+ + +

For a decade, test automation had a comfortable assumption baked into it: given the same input, the system + under test returns the same output. Assert on that output, and you have a test. Large language models broke + that assumption. Ask an LLM the same question twice and you can get two differently-worded answers that are + both correct — or two that are both subtly wrong. As a QA engineer, "assert + response == expected" simply doesn't work anymore. +

+ +

This is the gap DeepEval fills, and it's + become the tool I reach for first when a project ships anything AI-powered.

+ +

What DeepEval actually is

+

DeepEval is an open-source LLM evaluation framework from Confident AI. The single most important thing to + understand about it — especially if you come from a Selenium/Cypress/Playwright background — is that it's + a pytest plugin. If you've ever written a unit test in Python, DeepEval feels instantly familiar. You + write test cases, you run deepeval test run, and you get pass/fail results you can gate a pipeline + on.

+

The difference is how it decides pass or fail. Instead of comparing strings byte-for-byte, DeepEval + scores outputs using a mix of LLM-as-a-judge evaluation, natural language inference (NLI) + models, and statistical methods. That lets it measure fuzzy, human qualities — relevancy, faithfulness, + hallucination, bias, tool-calling correctness — the things that actually matter for an LLM feature.

+ +

The metric that changes everything: G-Eval

+

Out of the 50+ metrics DeepEval ships in 2026, the one worth learning first is G-Eval. G-Eval + uses an LLM-as-a-judge with chain-of-thought reasoning to evaluate output against any custom criteria you + describe in plain English.

+

That is a genuinely new capability for a QA engineer. You can write an acceptance criterion the same way a + product owner would phrase it — "the answer must not promise a refund timeline" — and turn it into an automated, + repeatable check.

+ +
from deepeval import assert_test
+from deepeval.metrics import GEval
+from deepeval.test_case import LLMTestCase, LLMTestCaseParams
+
+correctness = GEval(
+    name="Correctness",
+    criteria="Determine whether the actual output is factually "
+             "correct and does not contradict the expected answer.",
+    evaluation_params=[
+        LLMTestCaseParams.INPUT,
+        LLMTestCaseParams.ACTUAL_OUTPUT,
+        LLMTestCaseParams.EXPECTED_OUTPUT,
+    ],
+    threshold=0.5,
+)
+
+def test_billing_answer():
+    test_case = LLMTestCase(
+        input="How long do refunds take?",
+        actual_output="Refunds are processed within 5-7 business days.",
+        expected_output="Refunds take 5 to 7 business days.",
+    )
+    assert_test(test_case, [correctness])
+ +

Run that with deepeval test run test_billing.py and it behaves like any other pytest suite — green + when the criterion holds, red (with a reasoned explanation) when it doesn't.

+ +

The metrics QA teams lean on most

+

Beyond G-Eval, a handful of built-in metrics cover the majority of real-world LLM bugs:

+
    +
  • Answer Relevancy — is the response actually addressing the question, or wandering off?
  • +
  • Faithfulness — for RAG systems, does the answer stay true to the retrieved context, or is + the model inventing things?
  • +
  • Hallucination — is the model stating facts that aren't supported by any provided source? +
  • +
  • Contextual Precision / Recall — is your retrieval step surfacing the right + documents in the right order?
  • +
  • Bias & Toxicity — safety gates you genuinely want failing loudly in CI.
  • +
+

For a Retrieval-Augmented Generation app, Faithfulness plus Contextual Recall together tell you whether a bad + answer is the retriever's fault or the model's fault — a distinction that used to take hours of + manual debugging.

+ +

Wiring it into CI/CD

+

Because DeepEval is pytest-native, the CI story is boring in the best possible way. It's the same pattern I + already use for Cypress and Playwright suites:

+
    +
  1. Store a dataset of representative inputs (a "golden set") as test cases.
  2. +
  3. Run deepeval test run as a stage in GitHub Actions or Jenkins.
  4. +
  5. Fail the build if any metric drops below its threshold.
  6. +
+

That converts "the AI feels worse this week" — an unfalsifiable complaint — into a red pipeline with a number + attached. It's the difference between vibes and a quality gate.

+ +
The mental shift for a QA engineer isn't the syntax — it's accepting that a score above a + threshold, not an exact match, is a legitimate pass condition.
+ +

Where DeepEval fits in a modern QA stack

+

I don't think of DeepEval as replacing anything. Your Playwright tests still verify the app renders and the + button works. DeepEval sits one layer deeper, verifying that the content the LLM produced is relevant, + grounded, and safe. On an AI product, you need both — and a QA engineer who can speak fluently about + hallucination rate and faithfulness scores is suddenly a lot more valuable than one who only knows locators.

+

If you're a test automation engineer watching AI features land in your product and wondering where you fit, + this is the answer: LLM evaluation is QA. DeepEval is the most approachable on-ramp I've found. Next, + see how Playwright + MCP brings AI agents into + browser testing.

+ +
+

Need a real quality gate for your AI feature?

+

I'm a Senior QA Automation Engineer specialising in AI test automation, Playwright, and CI/CD.

+ Let's connect on + LinkedIn +
+
+
+ + + + + + + + diff --git a/blog/deepeval-llm-testing-guide-for-qa-engineers.md b/blog/deepeval-llm-testing-guide-for-qa-engineers.md new file mode 100644 index 0000000..5f04910 --- /dev/null +++ b/blog/deepeval-llm-testing-guide-for-qa-engineers.md @@ -0,0 +1,88 @@ +--- +title: "DeepEval: LLM Testing for QA Engineers (A Practical 2026 Guide)" +description: "How QA automation engineers can test LLM and RAG apps with DeepEval — pytest-native LLM evaluation, G-Eval, hallucination and faithfulness metrics, and CI gating." +slug: deepeval-llm-testing-guide-for-qa-engineers +date: 2026-06-20 +author: Shubham Singh +tags: [AI Test Automation, DeepEval, LLM Testing, pytest, QA] +--- + +# DeepEval: LLM Testing for QA Engineers (A Practical 2026 Guide) + +For a decade, test automation had a comfortable assumption baked into it: given the same input, the system under test returns the same output. Assert on that output, and you have a test. Large language models broke that assumption. Ask an LLM the same question twice and you can get two differently-worded answers that are *both* correct — or two that are *both* subtly wrong. As a QA engineer, "assert `response == expected`" simply doesn't work anymore. + +This is the gap **[DeepEval](https://deepeval.com/)** fills, and it's become the tool I reach for first when a project ships anything AI-powered. + +## What DeepEval actually is + +DeepEval is an open-source LLM evaluation framework from Confident AI. The single most important thing to understand about it — especially if you come from a Selenium/Cypress/Playwright background — is that **it's a pytest plugin**. If you've ever written a unit test in Python, DeepEval feels instantly familiar. You write test cases, you run `deepeval test run`, and you get pass/fail results you can gate a pipeline on. + +The difference is *how* it decides pass or fail. Instead of comparing strings byte-for-byte, DeepEval scores outputs using a mix of **LLM-as-a-judge** evaluation, natural language inference (NLI) models, and statistical methods. That lets it measure fuzzy, human qualities — relevancy, faithfulness, hallucination, bias, tool-calling correctness — the things that actually matter for an LLM feature. + +## The metric that changes everything: G-Eval + +Out of the 50+ metrics DeepEval ships in 2026, the one worth learning first is **G-Eval**. G-Eval uses an LLM-as-a-judge with chain-of-thought reasoning to evaluate output against *any custom criteria you describe in plain English*. + +That is a genuinely new capability for a QA engineer. You can write an acceptance criterion the same way a product owner would phrase it — "the answer must not promise a refund timeline" — and turn it into an automated, repeatable check. + +```python +from deepeval import assert_test +from deepeval.metrics import GEval +from deepeval.test_case import LLMTestCase, LLMTestCaseParams + +correctness = GEval( + name="Correctness", + criteria="Determine whether the actual output is factually " + "correct and does not contradict the expected answer.", + evaluation_params=[ + LLMTestCaseParams.INPUT, + LLMTestCaseParams.ACTUAL_OUTPUT, + LLMTestCaseParams.EXPECTED_OUTPUT, + ], + threshold=0.5, +) + +def test_billing_answer(): + test_case = LLMTestCase( + input="How long do refunds take?", + actual_output="Refunds are processed within 5-7 business days.", + expected_output="Refunds take 5 to 7 business days.", + ) + assert_test(test_case, [correctness]) +``` + +Run that with `deepeval test run test_billing.py` and it behaves like any other pytest suite — green when the criterion holds, red (with a reasoned explanation) when it doesn't. + +## The metrics QA teams lean on most + +Beyond G-Eval, a handful of built-in metrics cover the majority of real-world LLM bugs: + +- **Answer Relevancy** — is the response actually addressing the question, or wandering off? +- **Faithfulness** — for RAG systems, does the answer stay true to the retrieved context, or is the model inventing things? +- **Hallucination** — is the model stating facts that aren't supported by any provided source? +- **Contextual Precision / Recall** — is your retrieval step surfacing the *right* documents in the *right* order? +- **Bias & Toxicity** — safety gates you genuinely want failing loudly in CI. + +For a Retrieval-Augmented Generation app, Faithfulness plus Contextual Recall together tell you whether a bad answer is the *retriever's* fault or the *model's* fault — a distinction that used to take hours of manual debugging. + +## Wiring it into CI/CD + +Because DeepEval is pytest-native, the CI story is boring in the best possible way. It's the same pattern I already use for Cypress and Playwright suites: + +1. Store a dataset of representative inputs (a "golden set") as test cases. +2. Run `deepeval test run` as a stage in GitHub Actions or Jenkins. +3. Fail the build if any metric drops below its threshold. + +That converts "the AI feels worse this week" — an unfalsifiable complaint — into a red pipeline with a number attached. It's the difference between vibes and a quality gate. + +> The mental shift for a QA engineer isn't the syntax — it's accepting that a *score above a threshold*, not an exact match, is a legitimate pass condition. + +## Where DeepEval fits in a modern QA stack + +I don't think of DeepEval as replacing anything. Your Playwright tests still verify the app renders and the button works. DeepEval sits one layer deeper, verifying that the *content* the LLM produced is relevant, grounded, and safe. On an AI product, you need both — and a QA engineer who can speak fluently about hallucination rate and faithfulness scores is suddenly a lot more valuable than one who only knows locators. + +If you're a test automation engineer watching AI features land in your product and wondering where you fit, this is the answer: LLM evaluation *is* QA. DeepEval is the most approachable on-ramp I've found. + +--- + +*Written by Shubham Singh, Senior QA Automation Engineer specialising in AI test automation. Have an AI feature that needs a real quality gate? [Let's connect on LinkedIn](https://www.linkedin.com/in/adminvns/).* diff --git a/blog/mobilewright-playwright-for-mobile-testing.html b/blog/mobilewright-playwright-for-mobile-testing.html new file mode 100644 index 0000000..cf4c96f --- /dev/null +++ b/blog/mobilewright-playwright-for-mobile-testing.html @@ -0,0 +1,246 @@ + + + + + + + + Mobilewright: Playwright for Mobile App Test Automation | Shubham Singh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +

Mobilewright: Playwright for Mobile App Test Automation

+ + +

Web test automation has had a clear winner for a while now — Playwright's auto-waiting, clean API, and + accessibility-first locators quietly made a lot of flaky Selenium suites obsolete. Mobile automation never had + that moment. Appium is powerful and battle-tested, but anyone who has set it up knows the ceremony: drivers, + capabilities, platform-specific selectors, and a fair amount of Thread.sleep() scattered around to + fight flakiness.

+ +

Mobilewright is the first tool I've used + that feels like it's trying to give mobile the "Playwright moment."

+ +

What it is

+

Mobilewright is an open-source (Apache 2.0) mobile automation framework from Mobile Next HQ — the same team + behind mobile-mcp. Its pitch is refreshingly direct: one deterministic API for both iOS and + Android, with the developer experience Playwright users already know. It's installed from npm, + written in TypeScript, and is actually built on top of Playwright.

+ +
npm install mobilewright
+ +

Crucially, it drives real devices, simulators, and emulators, and supports the frameworks + teams actually build with — UIKit, SwiftUI, Jetpack Compose, Android Views, React Native, Expo, + Cordova/Capacitor, and more. You're not locked into one UI stack.

+ +

The API will look familiar

+

Here's a login flow on iOS. If you've written Playwright, you already know how to read this:

+ +
import { ios, expect } from 'mobilewright';
+
+const device = await ios.launch({ bundleId: 'com.example.myapp' });
+const { screen } = device;
+
+await screen.getByLabel('Email').fill('user@example.com');
+await screen.getByLabel('Password').fill('password123');
+await screen.getByRole('button', { name: 'Sign In' }).tap();
+
+await expect(screen.getByText('Welcome back')).toBeVisible();
+await device.close();
+ +

No capabilities object, no driver setup, no explicit waits. That getByLabel / getByRole + vocabulary is the same semantic-locator philosophy that made Playwright reliable on the web, now pointed at a + mobile accessibility tree.

+ +

The three things that matter for flakiness

+

Flaky mobile tests almost always trace back to timing and brittle selectors. Mobilewright attacks both:

+
    +
  • Auto-waiting — every action waits for the element to be visible, enabled, and to have + stable bounds before interacting. That last part matters on mobile, where animations and layout + shifts cause half of all flakes.
  • +
  • Chainable, semantic locators — you compose intent, e.g. + screen.getByType('Cell').getByLabel('Item 1'), instead of hard-coding fragile XPaths.
  • +
  • Retry assertions — expect(locator).toBeVisible() polls until it's satisfied + or times out (5s by default), and supports negation with .not. No more sprinkling sleeps to "give + the screen a second."
  • +
+

There's also a zero-config CLI that auto-discovers booted simulators and can scaffold a + project, run tests, and verify your environment — so the first-run experience is minutes, not an afternoon.

+ +

The part that makes it a 2026 tool: AI agents

+

This is where Mobilewright gets genuinely interesting for where QA is heading. It's explicitly built for + AI agents. It exposes the device's accessibility tree deterministically — no vision model + required — and ships with mobile-mcp integration so an AI coding agent (Claude, Cursor, and friends) can drive a + real device or simulator through the Model Context + Protocol.

+

That mirrors exactly what Playwright's MCP server did for the web: give an agent a structured, reliable view of + the UI so it can act on meaning rather than pixels. Mobilewright is doing the same thing for mobile, and + it's from the team that built the MCP piece — so the two are designed to fit together.

+ +
Appium isn't going away — its ecosystem and device-cloud support are enormous. But for greenfield + mobile suites, Mobilewright's ergonomics are hard to argue with.
+ +

Should you adopt it yet?

+

An honest caveat: Mobilewright is young. At the time of writing it's around v0.0.49 (released + mid-July 2026), moving fast, with ~4,500 GitHub stars and growing. For a mission-critical release pipeline + today, I'd pilot it alongside an existing Appium suite rather than rip-and-replace. But the direction is clearly + right, and the API is stable enough to start learning now.

+

For QA engineers, the takeaway is simple: the skills you built on Playwright — semantic locators, auto-waiting, + web-first assertions — transfer almost directly to mobile through Mobilewright. That's a rare and valuable kind + of leverage.

+ +
+

Scaling mobile automation?

+

I build web, mobile, and AI-driven test automation as a Senior QA Automation Engineer.

+ Reach me on + LinkedIn +
+
+
+ + + + + + + + diff --git a/blog/mobilewright-playwright-for-mobile-testing.md b/blog/mobilewright-playwright-for-mobile-testing.md new file mode 100644 index 0000000..ad3f92d --- /dev/null +++ b/blog/mobilewright-playwright-for-mobile-testing.md @@ -0,0 +1,72 @@ +--- +title: "Mobilewright: Playwright for Mobile App Test Automation" +description: "Mobilewright brings the Playwright developer experience to iOS and Android — one deterministic API, auto-waiting, semantic locators, and AI-agent support. A QA engineer's first look." +slug: mobilewright-playwright-for-mobile-testing +date: 2026-07-05 +author: Shubham Singh +tags: [Mobile Testing, Mobilewright, Playwright, Appium, QA Automation] +--- + +# Mobilewright: Playwright for Mobile App Test Automation + +Web test automation has had a clear winner for a while now — Playwright's auto-waiting, clean API, and accessibility-first locators quietly made a lot of flaky Selenium suites obsolete. Mobile automation never had that moment. Appium is powerful and battle-tested, but anyone who has set it up knows the ceremony: drivers, capabilities, platform-specific selectors, and a fair amount of `Thread.sleep()` scattered around to fight flakiness. + +**[Mobilewright](https://mobilewright.dev/)** is the first tool I've used that feels like it's trying to give mobile the "Playwright moment." + +## What it is + +Mobilewright is an open-source (Apache 2.0) mobile automation framework from Mobile Next HQ — the same team behind mobile-mcp. Its pitch is refreshingly direct: **one deterministic API for both iOS and Android**, with the developer experience Playwright users already know. It's installed from npm, written in TypeScript, and is actually built on top of Playwright. + +```bash +npm install mobilewright +``` + +Crucially, it drives **real devices, simulators, and emulators**, and supports the frameworks teams actually build with — UIKit, SwiftUI, Jetpack Compose, Android Views, React Native, Expo, Cordova/Capacitor, and more. You're not locked into one UI stack. + +## The API will look familiar + +Here's a login flow on iOS. If you've written Playwright, you already know how to read this: + +```javascript +import { ios, expect } from 'mobilewright'; + +const device = await ios.launch({ bundleId: 'com.example.myapp' }); +const { screen } = device; + +await screen.getByLabel('Email').fill('user@example.com'); +await screen.getByLabel('Password').fill('password123'); +await screen.getByRole('button', { name: 'Sign In' }).tap(); + +await expect(screen.getByText('Welcome back')).toBeVisible(); +await device.close(); +``` + +No capabilities object, no driver setup, no explicit waits. That `getByLabel` / `getByRole` vocabulary is the same semantic-locator philosophy that made Playwright reliable on the web, now pointed at a mobile accessibility tree. + +## The three things that matter for flakiness + +Flaky mobile tests almost always trace back to timing and brittle selectors. Mobilewright attacks both: + +- **Auto-waiting** — every action waits for the element to be visible, enabled, and to have *stable bounds* before interacting. That last part matters on mobile, where animations and layout shifts cause half of all flakes. +- **Chainable, semantic locators** — you compose intent, e.g. `screen.getByType('Cell').getByLabel('Item 1')`, instead of hard-coding fragile XPaths. +- **Retry assertions** — `expect(locator).toBeVisible()` polls until it's satisfied or times out (5s by default), and supports negation with `.not`. No more sprinkling sleeps to "give the screen a second." + +There's also a **zero-config CLI** that auto-discovers booted simulators and can scaffold a project, run tests, and verify your environment — so the first-run experience is minutes, not an afternoon. + +## The part that makes it a 2026 tool: AI agents + +This is where Mobilewright gets genuinely interesting for where QA is heading. It's explicitly **built for AI agents**. It exposes the device's accessibility tree *deterministically* — no vision model required — and ships with mobile-mcp integration so an AI coding agent (Claude, Cursor, and friends) can drive a real device or simulator through the [Model Context Protocol](/blog/playwright-mcp-ai-browser-automation.html). + +That mirrors exactly what Playwright's MCP server did for the web: give an agent a structured, reliable view of the UI so it can act on *meaning* rather than pixels. Mobilewright is doing the same thing for mobile, and it's from the team that built the MCP piece — so the two are designed to fit together. + +> Appium isn't going away — its ecosystem and device-cloud support are enormous. But for greenfield mobile suites, Mobilewright's ergonomics are hard to argue with. + +## Should you adopt it yet? + +An honest caveat: Mobilewright is young. At the time of writing it's around **v0.0.49** (released mid-July 2026), moving fast, with ~4,500 GitHub stars and growing. For a mission-critical release pipeline today, I'd pilot it alongside an existing Appium suite rather than rip-and-replace. But the direction is clearly right, and the API is stable enough to start learning now. + +For QA engineers, the takeaway is simple: the skills you built on Playwright — semantic locators, auto-waiting, web-first assertions — transfer almost directly to mobile through Mobilewright. That's a rare and valuable kind of leverage. + +--- + +*Written by Shubham Singh, Senior QA Automation Engineer working across web, mobile, and AI-driven testing. Building out mobile automation and want a second opinion? [Reach me on LinkedIn](https://www.linkedin.com/in/adminvns/).* diff --git a/blog/playwright-mcp-ai-browser-automation.html b/blog/playwright-mcp-ai-browser-automation.html new file mode 100644 index 0000000..e97524e --- /dev/null +++ b/blog/playwright-mcp-ai-browser-automation.html @@ -0,0 +1,244 @@ + + + + + + + + Playwright + MCP: How AI Agents Drive Browser Automation | Shubham Singh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +

Playwright + MCP: How AI Agents Now Drive Browser Automation

+ + +

If you've spent any time in test automation, you know the two hard problems: writing the scripts, and keeping + them from breaking every time a developer renames a CSS class. The pairing of Playwright with + the Model Context Protocol (MCP) takes a serious run at both — and it's reshaped how I think + about AI in a QA workflow over the last year.

+ +

First, what MCP is

+

The Model Context Protocol is an open standard for connecting large language models to external + tools and data through a unified client–server architecture. Think of it as a universal adapter: instead of + every AI app inventing its own way to "use a tool," MCP defines one protocol, and any compliant client (VS Code, + Cursor, Windsurf, Claude Desktop) can talk to any compliant server.

+

Playwright MCP — + Microsoft's reference server — exposes Playwright's browser automation as an MCP server. That means an + AI agent can open a browser, navigate, click, type, and assert, all through a standard protocol.

+ +

The key insight: it works on the accessibility tree, not pixels

+

This is the detail every QA engineer needs to understand, because it's why the approach is reliable. +

+

Playwright MCP does not drive the browser with screenshots and a vision model. When a tool + runs, it returns a structured accessibility snapshot — the page's elements, their roles, and + their text content. The agent reasons over that structured data and picks its next action.

+

The practical consequences are big:

+
    +
  • Deterministic — the agent acts on element roles and names, not fuzzy pixel guesses.
  • +
  • Fast and cheap-ish — no image encoding on every step.
  • +
  • Robust to visual change — a restyled button with the same role and label is still + findable.
  • +
+

This is the same philosophy that makes ordinary Playwright locators stable, applied to an autonomous agent.

+ +

From scripts to test agents

+

Traditional automation executes pre-written steps. A Playwright test agent flips the model: + it's an LLM-driven execution loop wrapped around Playwright's tools. You hand it intent — "complete the + checkout flow and verify the success modal appears" — and it inspects the accessibility tree, decides which tool + to call, acts, observes the result, and repeats until the goal is met.

+

For exploratory testing and rapidly-changing UIs, this is powerful. The agent adapts to a UI it hasn't seen + before instead of throwing a NoSuchElementException the moment a selector drifts.

+ +
// Example: registering Playwright MCP with an MCP client
+{
+  "mcpServers": {
+    "playwright": {
+      "command": "npx",
+      "args": ["@playwright/mcp@latest"]
+    }
+  }
+}
+ +

Point a client like Claude Desktop or Cursor at that, and it can drive a real browser on your behalf.

+ +

The 2026 reality check: the token-cost debate

+

I want to be balanced here, because there's genuine nuance the hype skips over. MCP is not automatically the + right tool for every job, and the community has spent 2026 arguing about exactly this.

+

The friction is token cost. Because the MCP server streams a full accessibility snapshot back + to the model on each step, agentic MCP runs can be expensive — reported figures put a single MCP-driven test + around ~114K tokens, versus roughly ~27K tokens for a comparable + CLI-skill-based workflow. That's a 4x difference, and at scale it's real money.

+

The result is a growing counter-trend: many coding agents now favour CLI-based "skills" — + concise, purpose-built commands — over chatty MCP round-trips for well-defined tasks. MCP has + consolidated the agentic-Playwright ecosystem around one protocol (Microsoft's server is the default, + with several specialised alternatives competing on token efficiency), but "use MCP for everything" is not the + 2026 consensus.

+ +
My rule of thumb: reach for a Playwright test agent on MCP when you need adaptive, + goal-driven exploration of an unfamiliar or volatile UI. For deterministic, high-volume regression, a plain + scripted Playwright suite — or a tight CLI skill — is still cheaper and more predictable.
+ +

Why this matters for your QA career

+

The engineers who will thrive aren't the ones who can write the most page.click() calls — agents + will increasingly do that. They're the ones who understand when to hand a task to an agent, how to keep + it grounded (accessibility tree over pixels), and how to reason about the cost/reliability trade-off. Playwright + + MCP is the clearest place to build that intuition today.

+

Pair it with mobile — where Mobilewright is + bringing the same accessibility-tree-plus-MCP model to iOS and Android — and you can see the shape of the next + few years of test automation forming.

+ +
+

Exploring agentic testing for your team?

+

I'm a Senior QA Automation Engineer working with Playwright, MCP, and modern CI/CD.

+ Connect on + LinkedIn +
+
+
+ + + + + + + + diff --git a/blog/playwright-mcp-ai-browser-automation.md b/blog/playwright-mcp-ai-browser-automation.md new file mode 100644 index 0000000..228a532 --- /dev/null +++ b/blog/playwright-mcp-ai-browser-automation.md @@ -0,0 +1,72 @@ +--- +title: "Playwright + MCP: How AI Agents Now Drive Browser Automation" +description: "A QA engineer's guide to Playwright MCP — how the Model Context Protocol lets AI agents drive the browser via the accessibility tree, plus the 2026 token-cost debate over MCP vs CLI skills." +slug: playwright-mcp-ai-browser-automation +date: 2026-07-14 +author: Shubham Singh +tags: [Playwright, MCP, AI Test Automation, Browser Automation, QA] +--- + +# Playwright + MCP: How AI Agents Now Drive Browser Automation + +If you've spent any time in test automation, you know the two hard problems: writing the scripts, and keeping them from breaking every time a developer renames a CSS class. The pairing of **Playwright** with the **Model Context Protocol (MCP)** takes a serious run at both — and it's reshaped how I think about AI in a QA workflow over the last year. + +## First, what MCP is + +The **Model Context Protocol** is an open standard for connecting large language models to external tools and data through a unified client–server architecture. Think of it as a universal adapter: instead of every AI app inventing its own way to "use a tool," MCP defines one protocol, and any compliant client (VS Code, Cursor, Windsurf, Claude Desktop) can talk to any compliant server. + +**[Playwright MCP](https://playwright.dev/docs/getting-started-mcp)** — Microsoft's reference server — exposes Playwright's browser automation *as* an MCP server. That means an AI agent can open a browser, navigate, click, type, and assert, all through a standard protocol. + +## The key insight: it works on the accessibility tree, not pixels + +This is the detail every QA engineer needs to understand, because it's *why* the approach is reliable. + +Playwright MCP does **not** drive the browser with screenshots and a vision model. When a tool runs, it returns a **structured accessibility snapshot** — the page's elements, their roles, and their text content. The agent reasons over that structured data and picks its next action. + +The practical consequences are big: + +- **Deterministic** — the agent acts on element roles and names, not fuzzy pixel guesses. +- **Fast and cheap-ish** — no image encoding on every step. +- **Robust to visual change** — a restyled button with the same role and label is still findable. + +This is the same philosophy that makes ordinary Playwright locators stable, applied to an autonomous agent. + +## From scripts to test *agents* + +Traditional automation executes pre-written steps. A **Playwright test agent** flips the model: it's an LLM-driven execution loop wrapped around Playwright's tools. You hand it *intent* — "complete the checkout flow and verify the success modal appears" — and it inspects the accessibility tree, decides which tool to call, acts, observes the result, and repeats until the goal is met. + +For exploratory testing and rapidly-changing UIs, this is powerful. The agent adapts to a UI it hasn't seen before instead of throwing a `NoSuchElementException` the moment a selector drifts. + +```jsonc +// Example: registering Playwright MCP with an MCP client +{ + "mcpServers": { + "playwright": { + "command": "npx", + "args": ["@playwright/mcp@latest"] + } + } +} +``` + +Point a client like Claude Desktop or Cursor at that, and it can drive a real browser on your behalf. + +## The 2026 reality check: the token-cost debate + +I want to be balanced here, because there's genuine nuance the hype skips over. MCP is not automatically the right tool for every job, and the community has spent 2026 arguing about exactly this. + +The friction is **token cost**. Because the MCP server streams a full accessibility snapshot back to the model on each step, agentic MCP runs can be expensive — reported figures put a single MCP-driven test around **~114K tokens**, versus roughly **~27K tokens** for a comparable CLI-skill-based workflow. That's a 4x difference, and at scale it's real money. + +The result is a growing counter-trend: many coding agents now favour **CLI-based "skills"** — concise, purpose-built commands — over chatty MCP round-trips for well-defined tasks. MCP has *consolidated* the agentic-Playwright ecosystem around one protocol (Microsoft's server is the default, with several specialised alternatives competing on token efficiency), but "use MCP for everything" is not the 2026 consensus. + +> My rule of thumb: reach for a Playwright *test agent* on MCP when you need adaptive, goal-driven exploration of an unfamiliar or volatile UI. For deterministic, high-volume regression, a plain scripted Playwright suite — or a tight CLI skill — is still cheaper and more predictable. + +## Why this matters for your QA career + +The engineers who will thrive aren't the ones who can write the most `page.click()` calls — agents will increasingly do that. They're the ones who understand *when* to hand a task to an agent, how to keep it grounded (accessibility tree over pixels), and how to reason about the cost/reliability trade-off. Playwright + MCP is the clearest place to build that intuition today. + +Pair it with mobile — where [Mobilewright](/blog/mobilewright-playwright-for-mobile-testing.html) is bringing the same accessibility-tree-plus-MCP model to iOS and Android — and you can see the shape of the next few years of test automation forming. + +--- + +*Written by Shubham Singh, Senior QA Automation Engineer focused on AI-driven test automation with Playwright, MCP, and modern CI/CD. Want to talk agentic testing? [Connect on LinkedIn](https://www.linkedin.com/in/adminvns/).* diff --git a/index.html b/index.html index 0b0e10d..603a115 100644 --- a/index.html +++ b/index.html @@ -5,51 +5,165 @@ - Shubham Singh | Senior QA Automation & DevOps Engineer + Shubham Singh — Senior QA Automation Engineer | AI Test Automation + + + + - + + + - + + content="Senior QA Automation Engineer at GlobalLogic (Hitachi) with 5+ years in AI-driven test automation — Playwright, Cypress, Selenium, Appium, DeepEval, API testing, AWS & CI/CD."> + + + - - - - - + + + + + + + + + + + + @@ -109,7 +223,7 @@
- + Shubham Singh, Senior QA Automation Engineer

Shubham Singh