<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Jags's Blog]]></title><description><![CDATA[I write about test automation, CI &amp; CD and tech in general. Follow me on Twitter @vaikuntj for a curated selection of ideas, insights, and inspiration.]]></description><link>https://jagannath.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 04:34:18 GMT</lastBuildDate><atom:link href="https://jagannath.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Papershelf]]></title><description><![CDATA[The ArXiv Shelf: Featured Research on Agents and AI

A Generalist Agent

Agents are not Enough



Automating Quality: Research Papers on Test Automation

Software Testing with Large Language Models: Survey, Landscape, and Vision —> March 2024

Chatti...]]></description><link>https://jagannath.dev/papershelf</link><guid isPermaLink="true">https://jagannath.dev/papershelf</guid><category><![CDATA[arxiv]]></category><category><![CDATA[papers]]></category><category><![CDATA[test-automation]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Tue, 14 Jan 2025 00:33:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/xG8IQMqMITM/upload/1647510264ffb100cdeab3565d119b74.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ul>
<li><p>The ArXiv Shelf: Featured Research on Agents and AI</p>
<ul>
<li><p><a target="_blank" href="https://arxiv.org/abs/2205.06175">A Generalist Agent</a></p>
</li>
<li><p><a target="_blank" href="https://www.arxiv.org/pdf/2412.16241">Agents are not Enough</a></p>
</li>
</ul>
</li>
<li><p>Automating Quality: Research Papers on Test Automation</p>
<ul>
<li><p><a target="_blank" href="https://arxiv.org/pdf/2307.07221">Software Testing with Large Language Models: Survey, Landscape, and Vision —&gt; March 2024</a></p>
</li>
<li><p><a target="_blank" href="https://arxiv.org/pdf/2305.09434">Chatting with GPT-3 for Zero-Shot Human-Like Mobile Automated GUI Testing</a></p>
</li>
<li><p><a target="_blank" href="https://arxiv.org/pdf/2310.15780">Make LLM a Testing Expert: Bringing Human-like Interaction to Mobile GUI Testing via Functionality-aware Decisions</a></p>
</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[My 2025 Bookshelf]]></title><description><![CDATA[Books

The Art of Doing Science and Engineering: Learning to Learn by Richard Hamming

Make your Bed by William H. McRaven

The Distance of the Moon by Italo Calvino]]></description><link>https://jagannath.dev/my-2025-bookshelf</link><guid isPermaLink="true">https://jagannath.dev/my-2025-bookshelf</guid><category><![CDATA[books]]></category><category><![CDATA[reading]]></category><category><![CDATA[bookshelf]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Wed, 08 Jan 2025 02:39:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1736303813149/decc734c-e107-4f28-a494-6fb795fba248.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ul>
<li><p>Books</p>
<ul>
<li><p>The Art of Doing Science and Engineering: Learning to Learn by Richard Hamming</p>
</li>
<li><p>Make your Bed by William H. McRaven</p>
</li>
<li><p>The Distance of the Moon by Italo Calvino</p>
</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering API Testing: A Comparison of HAR Files and Mocking Techniques]]></title><description><![CDATA[When testing API interactions, you have two primary options: using HAR (HTTP Archive) files or mocking. Each method has its strengths and weaknesses, and the choice between them depends on your specific testing needs.
Use HAR Files for:

Complex, mul...]]></description><link>https://jagannath.dev/mastering-api-testing-a-comparison-of-har-files-and-mocking-techniques</link><guid isPermaLink="true">https://jagannath.dev/mastering-api-testing-a-comparison-of-har-files-and-mocking-techniques</guid><category><![CDATA[Mocking]]></category><category><![CDATA[har]]></category><category><![CDATA[test-automation]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Wed, 18 Sep 2024 03:24:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731327562563/a802598a-9dfe-435c-a362-bc3bb7e2fcae.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When testing API interactions, you have two primary options: using HAR (HTTP Archive) files or mocking. Each method has its strengths and weaknesses, and the choice between them depends on your specific testing needs.</p>
<p><strong>Use HAR Files for:</strong></p>
<ul>
<li><p>Complex, multi-step requests that involve multiple network calls</p>
</li>
<li><p>Requests with dynamic data, such as timestamps or session IDs</p>
</li>
<li><p>Testing scenarios where the actual API response matters</p>
</li>
</ul>
<p>When using HAR files, it's essential to sanitize the recorded traffic to ensure that sensitive information is not leaked. Santization techniques can be used to remove sensitive data from the HAR file, such as:</p>
<ul>
<li><p>Masking sensitive information like passwords, API keys, user tokens or credit card numbers</p>
</li>
<li><p>Removing personal identifiable information (PII) like names and email addresses</p>
</li>
<li><p>Redacting unnecessary details that don't affect the test outcome</p>
</li>
</ul>
<p>Recording actual network traffic using HAR files allows you to test your application's behavior in a more realistic way. This approach is particularly useful when testing scenarios that involve multiple requests with complex dependencies or error handling.</p>
<p><strong>Use Mocking for:</strong></p>
<ul>
<li><p>Simple, single-response APIs that don't require complex setup or tear-down logic</p>
</li>
<li><p>Testing specific API responses without worrying about the underlying network calls</p>
</li>
<li><p>Rapidly prototyping or testing individual API endpoints</p>
</li>
</ul>
<p>Mocking a specific API response enables you to quickly test and validate your application's behavior against a known, expected response. This approach is ideal for simple APIs or when you need to focus on a single endpoint.</p>
<p><strong>Mocking Multiple API Requests</strong></p>
<p>Instead of using HAR files, you can also use mocking to simulate multiple API requests. This approach allows you to control the responses for each request individually, which can be useful when testing complex scenarios that involve multiple API calls.</p>
<p>For example, you could mock the response for an initial API request, then mock the response for a subsequent API request based on the result of the first request. This way, you have more flexibility and control over the testing process.</p>
<p><strong>Pros and Cons</strong></p>
<p>Using mocking to simulate multiple API requests has its pros and cons:</p>
<ul>
<li><p>Pros:</p>
<ul>
<li><p>More control over the testing process</p>
</li>
<li><p>Can be useful when testing complex scenarios that involve multiple API calls</p>
</li>
<li><p>Allows for easier error handling and scenario setup</p>
</li>
</ul>
</li>
<li><p>Cons:</p>
<ul>
<li><p>Requires more code and setup effort compared to using a HAR file</p>
</li>
<li><p>May lead to more complexity in your test code if not managed properly</p>
</li>
</ul>
</li>
</ul>
<p><strong>In Summary</strong></p>
<p>When you need to test complex, multi-step requests or dynamic data scenarios, use HAR files. For simple, single-response APIs or rapid prototyping, use mocking. By understanding the strengths and weaknesses of each approach, you can choose the right method for your testing needs and ensure that your application behaves as expected in various scenarios.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Playwright: Learn secure HAR-Based Mocking in Playwright]]></title><description><![CDATA[To start, you'll need to record all necessary network calls into a HAR (HTTP Archive) file. The process for doing so varies slightly depending on the browser you're using.
Next, you'll want to sanitize your HAR file to remove any sensitive informatio...]]></description><link>https://jagannath.dev/mastering-playwright-learn-secure-har-based-mocking-in-playwright</link><guid isPermaLink="true">https://jagannath.dev/mastering-playwright-learn-secure-har-based-mocking-in-playwright</guid><category><![CDATA[playwright]]></category><category><![CDATA[test-automation]]></category><category><![CDATA[Mocking]]></category><category><![CDATA[har]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Wed, 18 Sep 2024 01:22:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731327942946/6eb5ef6b-87dc-4804-a4fc-bc4eed66d352.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To start, you'll need to record all necessary network calls into a HAR (HTTP Archive) file. The process for doing so varies slightly depending on the browser you're using.</p>
<p>Next, you'll want to sanitize your HAR file to remove any sensitive information that could compromise security. This includes:</p>
<ul>
<li><p>Authorization headers and tokens</p>
</li>
<li><p>Traceparent and IP addresses</p>
</li>
<li><p>x-* headers (and any other headers you deem private or sensitive)</p>
</li>
</ul>
<p>You can use tools like <a target="_blank" href="https://har-">https://har-</a> <a target="_blank" href="https://har-sanitizer.pages.dev/"></a><a target="_blank" href="http://sanitizer.pages.dev/">sanitizer.pages.dev/</a> or <a target="_blank" href="https://github.com/google/har-sanitizer">https://github.com/google/har-sanitizer</a> to sanitize your HAR files. For a deeper dive into how sanitization works, you can check out the code at <a target="_blank" href="https://github.com/cloudflare/har-sanitizer/blob/main/src/lib/har_sanitize.tsx">https://github.com/cloudflare/har-sanitizer/blob/main/src/lib/har_sanitize.tsx</a></p>
<p>Finally, save your sanitized HAR file in a folder and update your Playwright code using the following as reference:</p>
<p>Docs: <a target="_blank" href="https://playwright.dev/docs/mock#mocking-with-har-files">https://playwright.dev/docs/mock#mocking-with-har-files</a></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">await</span> page.routeFromHAR(filePath, {
  url: <span class="hljs-string">'**/graphql'</span>,
  update: <span class="hljs-literal">false</span>
 });
<span class="hljs-keyword">await</span> page.reload();
</code></pre>
<p><strong>Test and Optimize:</strong><br />After setting up your HAR files, run your tests to ensure everything is working as expected. Use the results to optimize your tests and improve their efficiency.</p>
<p><strong>Using Fixtures:</strong><br />If you're using fixtures to manage your test data, you can add the following code to get started:</p>
<p><strong>Fixture Code for reference:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> applyHarFileMock = <span class="hljs-keyword">async</span> (page: Page, filePath: <span class="hljs-built_in">string</span>) =&gt;
  <span class="hljs-keyword">await</span> page.routeFromHAR(filePath, {
    url: <span class="hljs-string">'**/graphql'</span>,
    update: <span class="hljs-literal">false</span>,
  });
</code></pre>
<p><strong>Usage code for reference:</strong></p>
<pre><code class="lang-typescript">test.use({
  storageState: <span class="hljs-string">"&lt;path&gt;"</span>,
  actionTimeout: <span class="hljs-number">2000</span>,
  mockFromHarFile: <span class="hljs-string">'./e2e/har-files/sanitized_replay_har.har'</span>,
});
</code></pre>
<p>Note that this code should be tailored to your specific use case and testing environment.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Playwright: Ignoring CORS Limitations for Efficient Automation]]></title><description><![CDATA[Add the following options to your Playwright Config to disable CORS depending on your usecase.
 {
      use: {
        bypassCSP: true, // add this to disable cors
        launchOptions: {
          args: ['--disable-web-security'], // add this to di...]]></description><link>https://jagannath.dev/how-to-ignore-cors-in-playwright</link><guid isPermaLink="true">https://jagannath.dev/how-to-ignore-cors-in-playwright</guid><category><![CDATA[playwright]]></category><category><![CDATA[CORS]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Tue, 17 Sep 2024 04:04:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1731328320561/ac91ff45-f6a7-4252-b52e-3def9b74b618.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Add the following options to your Playwright Config to disable <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> depending on your usecase.</p>
<pre><code class="lang-javascript"> {
      <span class="hljs-attr">use</span>: {
        <span class="hljs-attr">bypassCSP</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// add this to disable cors</span>
        <span class="hljs-attr">launchOptions</span>: {
          <span class="hljs-attr">args</span>: [<span class="hljs-string">'--disable-web-security'</span>], <span class="hljs-comment">// add this to disable cors</span>
        },
      },
    }
</code></pre>
]]></content:encoded></item><item><title><![CDATA[The Curated Bookshelf for 2024]]></title><description><![CDATA[A 2024 Reading List for Personal Growth and Learning

Staff Engineer by Will Larson

Life 3.0 by Max Tegmark

Smart Money Strategy by Luke Smith]]></description><link>https://jagannath.dev/the-curated-bookshelf-for-2024</link><guid isPermaLink="true">https://jagannath.dev/the-curated-bookshelf-for-2024</guid><category><![CDATA[book shelf]]></category><category><![CDATA[books]]></category><category><![CDATA[2024]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Sun, 28 Jul 2024 02:43:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/K2Rrug-aWAg/upload/cdd8c30682d99b4bb0f3f8d2fbcb0347.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A 2024 Reading List for Personal Growth and Learning</p>
<ul>
<li><p>Staff Engineer by Will Larson</p>
</li>
<li><p>Life 3.0 by Max Tegmark</p>
</li>
<li><p>Smart Money Strategy by Luke Smith</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering Playwright: Effortless Custom User Agent Integration]]></title><description><![CDATA[The previous article detailed the process for modifying the user agent specifically for tests. However, it did not address how to alter the user agent globally within Playwright.
To update the global user agent in Playwright, refer to the following c...]]></description><link>https://jagannath.dev/mastering-playwright-effortless-custom-user-agent-integration</link><guid isPermaLink="true">https://jagannath.dev/mastering-playwright-effortless-custom-user-agent-integration</guid><category><![CDATA[playwright]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Thu, 29 Feb 2024 04:08:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709179600746/1942e777-8545-4305-8f6f-1d8f0de29319.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <a target="_blank" href="https://hashnode.com/post/cldjqhroi00080alj2amag9x7">previous article</a> detailed the process for modifying the user agent specifically for tests. However, it did not address how to alter the user agent globally within Playwright.</p>
<p>To update the global user agent in Playwright, refer to the following code snippet. Please adapt your <a target="_blank" href="https://playwright.dev/docs/test-global-setup-teardown">global setup</a> function using this as a guide:</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> config = GlobalConfiguration.getInstance({}),
    browser = <span class="hljs-keyword">await</span> config.getConfig().getBrowser(),
    context = <span class="hljs-keyword">await</span> browser.newContext({
      ...config.getPlaywrightConfig().use,
      userAgent: <span class="hljs-string">'made-up-user-agent'</span>,
    });
 <span class="hljs-keyword">await</span> context.tracing.start({ screenshots: <span class="hljs-literal">true</span>, snapshots: <span class="hljs-literal">true</span> });
 <span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> context.newPage();
  <span class="hljs-keyword">await</span> context.tracing.stop({
    path: <span class="hljs-string">'./&lt;trace-file-name&gt;.zip'</span>,
  });
  <span class="hljs-keyword">await</span> browser.close();
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Decoding the Dynamics of Compensation]]></title><description><![CDATA[Let's delve into the topic of PAY, an aspect frequently overlooked in empirical discussions.
It took me nearly a decade to grasp and articulate my salary expectations and requirements clearly. Throughout this journey, my understanding of PAY has deep...]]></description><link>https://jagannath.dev/decoding-the-dynamics-of-compensation</link><guid isPermaLink="true">https://jagannath.dev/decoding-the-dynamics-of-compensation</guid><category><![CDATA[Compensation]]></category><category><![CDATA[work life balance]]></category><category><![CDATA[Career]]></category><category><![CDATA[pay]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Sun, 25 Feb 2024 13:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708951524022/4ec5a631-e21e-40a8-96d1-f58cafbe330b.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's delve into the topic of PAY, an aspect frequently overlooked in empirical discussions.</p>
<p>It took me nearly a decade to grasp and articulate my salary expectations and requirements clearly. Throughout this journey, my understanding of PAY has deepened and evolved.</p>
<p>The interpretation of what PAY means has evolved and will keep evolving.</p>
<p>Sources such as :</p>
<ul>
<li><p><a target="_blank" href="https://www.kalzumeus.com/2012/01/23/salary-negotiation/">Kalzumeus salary negotiations</a></p>
</li>
<li><p><a target="_blank" href="https://georgestocker.com/2019/03/14/my-salary-progression-in-tech/">George Stocker's salary progression</a></p>
</li>
<li><p>The internet in general</p>
</li>
</ul>
<p>have helped me navigate this labyrinth.</p>
<p>Most of the articles I have read have been predominantly of US-based companies.</p>
<p>This helped me understand expectations and also confused me, because the pay structures and offerings in the US are different compared to other countries such as India &amp; Australia, among others.</p>
<p>To discern whether I align with or deviate from industry norms, I've relied on statistical analyses, drawing from sources like the Stack Overflow Developer Survey and data on salary distributions, perks, and work-life balance from peers across tech companies in similar fields. Conversations with recruiters have also shed light on the job market, pay scales, and benefits.</p>
<p>Sources used for these calculations are :</p>
<ul>
<li><p>Stack Overflow Developer Survey</p>
</li>
<li><p>Salary Distribution (including perks provided at a workplace + work-life balance), among peers across different tech companies in the same discipline</p>
</li>
<li><p>Inputs from Recruiters around what jobs are out there and pay structures + perks for those aforesaid jobs.</p>
</li>
</ul>
<p>Assumptions are taken while making this analysis:</p>
<ul>
<li><p>PAY = MONETARY SUM + PERKS + WORK-LIFE BALANCE</p>
</li>
<li><p>Not all opportunities are equal</p>
</li>
<li><p>One cannot just have an amazing career progression over some time, without being paid well. I have seen enough examples of it. You are free to disagree with this. You must not be an asshole/sexist/racist or any similar word or synonym.</p>
</li>
</ul>
<p>P.S.: Work-life balance, while integral, transcends mere job perks due to its subjective nature.</p>
<p>Let's now just talk about the Skills because this is the one of key factors which affect your PAY, the others being :</p>
<ul>
<li><p>Work Ethic &amp; Attitude</p>
</li>
<li><p>EQ + IQ</p>
</li>
<li><p>Interpersonal + Intra Personal Skills &amp; Intelligence</p>
</li>
</ul>
<p>If Potential Future Pay (let's say <code>PFP</code> for ease) can be represented as a function, it could be described loosely by the below equation :</p>
<ul>
<li><p>PFP current = Pay for Skills you bring to the table * relevance_factor of those skills * expertise_factor</p>
</li>
<li><p>The relevance_factor of those skills can also be termed as the Perceived value of those skills</p>
</li>
<li><p>Bargaining Power = expertise_factor(skills) * Relevance_factor(skills) * demand_factor of those skills</p>
</li>
<li><p>PFP future = PFP current * Bargaining Power + Perks at Job + Work-Life Balance</p>
</li>
</ul>
<p>Things to consider while thinking about your <strong>PFP</strong> future :</p>
<ul>
<li><p>Depending on the opportunity and your skills, you can deviate " + or - of 7.5 % "</p>
</li>
<li><p>When you think about Work-Life Balance, put a monetary value against it. Think of it as a $$ value you want to travel that extra 30 mins every day or whatever you feel is your work-life balance factor.</p>
</li>
<li><p>Luck is a small factor but not too small to ignore</p>
</li>
<li><p>It is easier to bring the skills from your initial opportunities &amp; quality of those opportunities</p>
</li>
<li><p>Self Learning helps a lot, especially in cases where your job doesn't provide you with the kind of things you want to work on. If you identify yourself in such a situation then start doing the required remedial work, to ensure the quality of your skill improves over time.</p>
</li>
<li><p>Having a mentor helps, but isn't always required. Enough great role models/mentors on the internet to help out. You define your parameters for performance and own it.</p>
</li>
<li><p>Discussing your salary with people whom you trust in the same sphere of work helps, to know where you are. This is not always easy and you may get burnt sometimes. For me, it was a real eye-opening experience, mostly positive.</p>
</li>
</ul>
<p>Market / Industry standards may not always help you in the negotiations. If you are getting paid below the "market/industry standards" you are severely underpaid, because I believe the standards in Software industry are skewed towards the lower end.</p>
<p>Conclusively, if you find yourself in a learning-rich yet lower-paying role, set a time limit on this phase. Continuous learning and skill enhancement are paramount. Always be collecting data, reassessing, and adapting.</p>
<p>Here's to navigating the complexities of compensation with insight and strategy. Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Art of Automation]]></title><description><![CDATA[Let's discuss automation, with a focus on Testing and Quality Assurance.
I intend this to be a personal benchmark - a reference point to revisit and gauge my progress over time. It aims to serve as a rubric, a structured framework for evaluation and ...]]></description><link>https://jagannath.dev/get-better-at-automation</link><guid isPermaLink="true">https://jagannath.dev/get-better-at-automation</guid><category><![CDATA[automation]]></category><category><![CDATA[learning]]></category><category><![CDATA[mindmaps]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Sun, 25 Feb 2024 13:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708950274123/38b07cd9-8e9e-40ec-945b-bec28b88760c.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's discuss automation, with a focus on Testing and Quality Assurance.</p>
<p>I intend this to be a personal benchmark - a reference point to revisit and gauge my progress over time. It aims to serve as a <a target="_blank" href="https://en.wikipedia.org/wiki/Rubric_(academic)">rubric</a>, a structured framework for evaluation and improvement.</p>
<p>Guidelines :</p>
<ul>
<li><p>Do you understand the concepts of</p>
<ul>
<li><p>Test Pyramid</p>
</li>
<li><p>CI /CD</p>
</li>
<li><p>Behavior-Driven Development (BDD)</p>
</li>
<li><p>Test-Driven Development (TDD)</p>
</li>
<li><p>Writing Unit tests, Integration tests and E2E tests . Identifying the differences between them.</p>
</li>
</ul>
</li>
<li><p><strong>Language Proficiency:</strong> :</p>
<ul>
<li><p>How comfortable are you with a given language e.g. : Java , Python , Scala, Erlang</p>
</li>
<li><p>Do you understand how to manage dependencies effectively and tooling provided for it in that particular language ecosystem.</p>
</li>
<li><p>Have you written / developed a working proof concept for the test automation framework.</p>
</li>
<li><p>Is there a way to enforce coding standards : Code Style Guides.</p>
</li>
</ul>
</li>
<li><p>Cloud &amp; Containers &amp; Everything in between</p>
<ul>
<li><p>Unlike 5 years ago, now we have Docker &amp; the cloud offerings (GCP &amp; AWS, etc.) have matured significantly. Hence, knowing these skills are important. The reasons being, more often than not,</p>
<ul>
<li><p>You work in a team.</p>
</li>
<li><p>The technical skills you pick up are easily augmented by real world experience. You can gain nuance and context around technical implementation. This is true for any skill, not just this particular one.</p>
</li>
</ul>
</li>
<li><p>Rate yourself on</p>
<ul>
<li><p>Comfort level with a Cloud Provider(s). You can always go for more.</p>
</li>
<li><p>Spinning up Jenkins or Buildkite based CI/CD solution. First manually and then via code.</p>
</li>
<li><p>Kubernetes Expertise and Usage.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>Have you written an</p>
<ul>
<li><p>API Test Automation Framework</p>
</li>
<li><p>UI Test Automation Framework</p>
</li>
<li><p>Performance / Load Test Automation Framework (backend)</p>
</li>
<li><p>Front End Performance Test Automation Framework</p>
</li>
<li><p>Mobile Test Automation Framework from scratch using the below as guidelines</p>
</li>
<li><p>Did you use any design patterns and coding principles (SOLID, Page Object, Clean Code)</p>
</li>
<li><p>Dependency Management</p>
</li>
<li><p>Exception Handling</p>
</li>
<li><p>Test Reporting</p>
</li>
<li><p>Parallelisation</p>
</li>
<li><p>Improving Determinism of the api tests</p>
</li>
<li><p>Using a hermetic environment ( via containers) to improve determinism and speed up the tests further more.</p>
</li>
<li><p>Run the API tests in CI</p>
</li>
<li><p>Synthetic Production monitoring i.e. run tests in prod to ensure a business workflow is functioning.</p>
</li>
</ul>
</li>
<li><p>Communication Skills</p>
</li>
<li><p>Mobile Testing</p>
<ul>
<li><p>Figure out reasons when to go native approach such as Espresso and XCUITest &amp; when to go something like Appium</p>
</li>
<li><p>CI/CD such as Bitrise.io</p>
</li>
<li><p>Comfort level around how app deployment and distribution works for an mobile ecosystem and any costs associated around it.</p>
</li>
</ul>
</li>
<li><p>Resources to you use for learning and Exploring</p>
<ul>
<li><p>Nothing like a real world implementation</p>
</li>
<li><p>YouTube Channels, Conferences &amp; Talks</p>
</li>
<li><p>Blogs</p>
</li>
<li><p>Tech Guides</p>
</li>
<li><p>Documentation</p>
</li>
<li><p>GitHub</p>
</li>
<li><p>Follow people on twitter, from whom you can learn.</p>
</li>
<li><p>Experiment and fail. You learn a lot from failures.</p>
</li>
</ul>
</li>
</ul>
<p>    One can build a mind map for each language ecosystem essentially, using the above info. Build yours and keep track of it.</p>
<ul>
<li>P.S. : Feedback is always welcome. You can tweet to me at : @vaikuntj .</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Firefox Shortcuts]]></title><description><![CDATA[Look into DNS

about:networking#dns


Filter all calls

on method:post & <filter> string in the domain section


How to override UserAgent in Firefox

Browse to "about:config"

Type "general.useragent.override"

From the three choices: Boolean, Numbe...]]></description><link>https://jagannath.dev/firefox-shortcuts</link><guid isPermaLink="true">https://jagannath.dev/firefox-shortcuts</guid><category><![CDATA[Firefox]]></category><category><![CDATA[Shortcuts]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Thu, 22 Feb 2024 23:56:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708646232359/4caefcb5-aa59-4037-bfda-a0c9d8eca57f.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<ul>
<li><p>Look into DNS</p>
<ul>
<li><code>about:networking#dns</code></li>
</ul>
</li>
<li><p>Filter all calls</p>
<ul>
<li>on method:post &amp; <code>&lt;filter&gt;</code> string in the domain section</li>
</ul>
</li>
<li><p>How to override UserAgent in Firefox</p>
<ul>
<li><p>Browse to "about:config"</p>
</li>
<li><p>Type "general.useragent.override"</p>
</li>
<li><p>From the three choices: Boolean, Number, and String, select <strong>String</strong> and update the user agent.</p>
</li>
<li><p>Open a new tab and see the updated user agent in the network calls</p>
</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[What does Shifting Left for testing mean ??]]></title><description><![CDATA[What shifting Left in the Testing/Quality perspective means
- Identifying the needs and dependencies of testing & related activities early in the planning cycle. This means understanding the following :

Dependencies of testing

Within a team

Techni...]]></description><link>https://jagannath.dev/what-does-shifting-left-for-testing-mean</link><guid isPermaLink="true">https://jagannath.dev/what-does-shifting-left-for-testing-mean</guid><category><![CDATA[shiftlefttesting]]></category><category><![CDATA[tests]]></category><category><![CDATA[automation testing ]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Wed, 06 Sep 2023 02:27:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708646898057/cf5270a6-dffd-48d9-92e9-3e9f1dbcc2a0.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-shifting-left-in-the-testingquality-perspective-means"><strong>What shifting Left in the Testing/Quality perspective means</strong></h3>
<p>- Identifying the needs and dependencies of testing &amp; related activities early in the planning cycle. This means understanding the following :</p>
<ul>
<li><p>Dependencies of testing</p>
<ul>
<li><p>Within a team</p>
<ul>
<li><p>Technical activities/experiments</p>
</li>
<li><p>Understanding the business requirements and plan accordingly</p>
</li>
</ul>
</li>
<li><p>Outside of teams</p>
<ul>
<li><p>Data that comes from other squads and teams</p>
</li>
<li><p>Impact on teams that depend on us for</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>A continuous feedback loop to react to changes and feedback</p>
</li>
<li><p>Automate your tests and ensure the tests are not flaky !!!</p>
<ul>
<li>If there are flaky tests then, the confidence in the system goes down</li>
</ul>
</li>
</ul>
<h3 id="heading-how-to-implement-the-shift-left-process"><strong>How to implement the Shift Left process ??</strong></h3>
<ul>
<li><p>Understand where you are in the journey</p>
</li>
<li><p>Make measurable changes</p>
<ul>
<li><p>See how you can measure progress. It could be</p>
<ul>
<li><p>Bugs that are caught earlier in the process</p>
</li>
<li><p>Issues prevented</p>
</li>
<li><p>Coverage of automated tests ==&gt; behaviors tested</p>
</li>
<li><p>Confidence a team has with releases</p>
</li>
<li><p>How easy is it to integrate feedback</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>The least disruptive way is to introduce changes incrementally (this works in most cases). Depending on the context, one may do it with a more big-bang approach</p>
</li>
<li><p>See what the team is comfortable with and what you are trying to achieve</p>
</li>
<li><p>The goal is to improve iteratively. It is okay to have a non-perfect start, as long as you improve the process and execution, you are good !!!!</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering Playwright :  Harnessing Parallel Execution]]></title><description><![CDATA[After developing your Playwright tests, they initially run smoothly. However, as the quantity of test cases grows, you notice a gradual increase in execution time. This leads to the critical question: How can you manage and optimize this process?
Ima...]]></description><link>https://jagannath.dev/parallelising-your-playwright-tests</link><guid isPermaLink="true">https://jagannath.dev/parallelising-your-playwright-tests</guid><category><![CDATA[playwright]]></category><category><![CDATA[test-automation]]></category><category><![CDATA[Docker]]></category><category><![CDATA[parallelism]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Mon, 21 Aug 2023 04:32:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709180012696/6df383db-11ac-4db2-b6d7-580300c0a72c.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After developing your Playwright tests, they initially run smoothly. However, as the quantity of test cases grows, you notice a gradual increase in execution time. This leads to the critical question: How can you manage and optimize this process?</p>
<p>Imagine managing 500 Playwright tests for your application. A strategic approach to handle this scenario involves several steps to improve efficiency and reduce runtimes.</p>
<h3 id="heading-categorizing-tests-for-parallel-execution">Categorizing Tests for Parallel Execution</h3>
<ul>
<li><p>Firstly, categorize the 500 tests into 4 or 5 distinct groups based on the features they test. By doing so, you can execute approximately 100 tests simultaneously across each category. This method not only accelerates the testing process but also localizes any failures to a specific block of 100 tests, streamlining the debugging process.</p>
</li>
<li><h3 id="heading-optimizing-authentication-flows">Optimizing Authentication Flows</h3>
<p>  In scenarios involving authentication, leverage fixtures to reuse authentication states, eliminating the need to log in for every test. This adjustment can significantly decrease the time required for each UI test.</p>
</li>
<li><h3 id="heading-leveraging-docker-for-consistent-environment">Leveraging Docker for Consistent Environment</h3>
<p>  Containerizing the testing environment ensures consistency across different machines and simplifies the setup process for new testing instances.</p>
</li>
</ul>
<h3 id="heading-utilizing-github-actions-for-test-parallelization">Utilizing GitHub Actions for Test Parallelization</h3>
<ul>
<li>GitHub Actions offers a convenient way to parallelize tests, further enhancing efficiency and reducing test execution times.</li>
</ul>
<h3 id="heading-running-tests-on-optimized-infrastructure">Running Tests on Optimized Infrastructure</h3>
<ul>
<li><p>Deploy your tests on a memory-optimized EC2 instance, such as a c5.4xlarge, allowing for up to 12 tests to run in parallel. Optimize costs by employing a combination of on-demand and spot instances, tailoring the infrastructure to your specific workload requirements.</p>
</li>
<li><p>Through these strategic measures, you can significantly improve the speed and efficiency of your Playwright testing suite, ensuring rapid feedback and high-quality software delivery. Use the following code for reference:</p>
</li>
<li><pre><code class="lang-dockerfile">        <span class="hljs-keyword">FROM</span> mcr.microsoft.com/playwright:v1.<span class="hljs-number">37.0</span>

        <span class="hljs-keyword">RUN</span><span class="bash"> mkdir -p /opt/google/chrome</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> ln -s /ms-playwright/chromium-1048/chrome-linux/chrome /opt/google/chrome/chrome</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> npm uninstall -g yarn &amp;&amp; \
            apt-get remove -y nodejs python3 --purge &amp;&amp; \
            apt-get update &amp;&amp; \
            apt-get install -y openjdk-11-jre uuid-runtime  &amp;&amp; \
            apt-get autoremove -y &amp;&amp; \
            apt-get clean -y &amp;&amp; \
            rm -rf /var/lib/apt/lists/*</span>

        <span class="hljs-comment"># Remove unused browser</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> rm -rf /ms-playwright/firefox-* /ms-playwright/webkit-*</span>

        <span class="hljs-comment"># Install nvm with node and npm</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> mkdir -p /usr/<span class="hljs-built_in">local</span>/nvm</span>
        <span class="hljs-keyword">ENV</span> NVM_DIR /usr/local/nvm
        <span class="hljs-keyword">ENV</span> NODE_VERSION v16.<span class="hljs-number">19.1</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> /bin/bash -c <span class="hljs-string">"source <span class="hljs-variable">$NVM_DIR</span>/nvm.sh &amp;&amp; nvm install <span class="hljs-variable">$NODE_VERSION</span> &amp;&amp; nvm use --delete-prefix <span class="hljs-variable">$NODE_VERSION</span>"</span></span>

        <span class="hljs-comment"># Add node and npm to the PATH</span>
        <span class="hljs-keyword">ENV</span> NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/bin
        <span class="hljs-keyword">ENV</span> PATH $NODE_PATH:$PATH

        <span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

        <span class="hljs-keyword">RUN</span><span class="bash"> npm install -g yarn --loglevel silent</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> wget https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.17.2/allure-commandline-2.17.2.tgz</span>
        <span class="hljs-keyword">RUN</span><span class="bash"> tar -xvzf allure-commandline-2.17.2.tgz &amp;&amp; rm -rf allure-commandline-2.17.2.tgz</span>
        <span class="hljs-keyword">ENV</span> PATH /app/allure-<span class="hljs-number">2.17</span>.<span class="hljs-number">2</span>/bin:$PATH

        <span class="hljs-keyword">RUN</span><span class="bash"> yarn install --cache-folder ~/.cache/yarn --frozen-lockfile --ignore-scripts</span>
</code></pre>
</li>
<li><h3 id="heading-simulating-the-api-responses-for-third-party-integrations">Simulating the API responses for third-party integrations</h3>
<ul>
<li><p>After implementing these adjustments, consider simulating the API responses for third-party integrations next. This strategy effectively eliminates a significant source of test instability.</p>
</li>
<li><p>To maintain the integrity of these simulated responses, it's crucial to validate that the mock data accurately reflects real API structures. Utilizing tools like <a target="_blank" href="https://zod.dev/">Zod</a> can help enforce consistency by verifying that the response structure remains unchanged over time.</p>
</li>
</ul>
</li>
</ul>
<p>    Remember, refining and enhancing the efficiency of your pipeline is an ongoing endeavor. Continuous evaluation and optimization are key to maintaining a swift and reliable testing process.</p>
]]></content:encoded></item><item><title><![CDATA[How to change User-Agent for WebdriverIO  & Playwright Tests]]></title><description><![CDATA[One may want to change/update the user agent for various use cases.
One such use case is :

Ensuring user analytics (e.g. Segment) is not triggered for your automated test cases. Not doing this may result in a higher analytics bill.

Solution:
The so...]]></description><link>https://jagannath.dev/how-to-change-user-agent-for-webdriverio-playwright-tests</link><guid isPermaLink="true">https://jagannath.dev/how-to-change-user-agent-for-webdriverio-playwright-tests</guid><category><![CDATA[Webdriver.io]]></category><category><![CDATA[playwright]]></category><category><![CDATA[test-automation]]></category><category><![CDATA[Segment analytics]]></category><category><![CDATA[configuration]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Tue, 31 Jan 2023 04:22:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1693354289334/62dbcc1e-624c-4226-9797-374bd96f5cb7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One may want to change/update the user agent for various use cases.</p>
<p>One such use case is :</p>
<ul>
<li>Ensuring user analytics (e.g. Segment) is not triggered for your automated test cases. Not doing this may result in a higher analytics bill.</li>
</ul>
<p><strong>Solution:</strong></p>
<p>The solution is to update your config and leave the tests untouched.</p>
<h3 id="heading-config-for-webdriverio-browserstack-run">Config for WebdriverIO BrowserStack Run</h3>
<pre><code class="lang-json">export const config: WebdriverIO.Config = {
  runner: 'local',
  specs: ['./features<span class="hljs-comment">/**/</span>*.feature'],
  exclude: [],
  maxInstances: <span class="hljs-number">2</span>,
  capabilities: [
    {
      'bstack:options': {
        os: process.env.OS_NAME || 'OS X',
        osVersion: process.env.OS_VERSION || 'Big Sur',
      },
      browserName: 'Chrome',
      browserVersion: 'latest',
      'goog:chromeOptions': {
        args: ['user-agent=madeup-user-agent-name'],
      },
    },
  ],
}
</code></pre>
<h3 id="heading-config-for-webdriverio-local-run">Config for WebDriverIO Local Run</h3>
<pre><code class="lang-json">export const config: WebdriverIO.Config = {
  runner: 'local',
  specs: ['./features<span class="hljs-comment">/**/</span>*.feature'],
  exclude: [],
  maxInstances: <span class="hljs-number">10</span>,
  capabilities: [
    {
      maxInstances: <span class="hljs-number">1</span>,
      browserName: 'chrome',
      acceptInsecureCerts: <span class="hljs-literal">true</span>,
      'goog:chromeOptions': {
        args: ['user-agent=madeup-user-agent-name'],
      },
    },
  ],
}
</code></pre>
<h3 id="heading-config-for-playwright-local-run">Config for Playwright Local Run</h3>
<pre><code class="lang-json">const config: PlaywrightTestConfig = {
   use: {
    ignoreHTTPSErrors: <span class="hljs-literal">true</span>,
    contextOptions: {
      bypassCSP: <span class="hljs-literal">true</span>,
      recordVideo: {
        dir: 'e2e/videos',
      },
      userAgent: 'madeup-user-agent-name',
    },
    headless: <span class="hljs-literal">true</span>,
    screenshot: 'only-on-failure',
    trace: 'on',
    video: 'retain-on-failure',
  },
};
export default config;
</code></pre>
<h3 id="heading-config-for-playwright-docker-run">Config for Playwright Docker Run</h3>
<pre><code class="lang-json">import { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
  use: {
    headless: <span class="hljs-literal">true</span>,
    navigationTimeout: <span class="hljs-number">30000</span>,
    actionTimeout: <span class="hljs-number">10000</span>,
    screenshot: 'only-on-failure',
    ignoreHTTPSErrors: <span class="hljs-literal">true</span>,
    contextOptions: {
      bypassCSP: <span class="hljs-literal">true</span>,
    },
  },
  projects: [
    {
      name: 'Chrome',
      use: {
        browserName: 'chromium',
        contextOptions: {
          ignoreHTTPSErrors: <span class="hljs-literal">true</span>,
          userAgent: 'madeup-user-agent-name',
        },
      },
    },
  ],
};
export default config;
</code></pre>
<p><strong>Resources</strong></p>
<ul>
<li><a target="_blank" href="https://github.com/microsoft/playwright/issues/11829">https://github.com/microsoft/playwright/issues/11829</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Searching your Git logs]]></title><description><![CDATA[Add the following function to your .zshrc file & then source ~/.zshrcThis search is case insensitive
function gsearch(){ 
git log -3 -i --grep="$1" --pretty=format:'%h %s [%an]'
}

Usage :
gsearch wip]]></description><link>https://jagannath.dev/searching-your-git-logs</link><guid isPermaLink="true">https://jagannath.dev/searching-your-git-logs</guid><category><![CDATA[Git]]></category><category><![CDATA[Logs]]></category><category><![CDATA[search]]></category><category><![CDATA[Developer]]></category><category><![CDATA[command line]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Fri, 06 Jan 2023 02:34:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/8kCixqfgXjU/upload/fb1d3baff8acc1d97713ee0c0748a9ae.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Add the following function to your <strong>.zshrc</strong> file &amp; then <strong>source ~/.zshrc</strong><br /><strong>This search is case insensitive</strong></p>
<pre><code class="lang-bash"><span class="hljs-keyword">function</span> <span class="hljs-function"><span class="hljs-title">gsearch</span></span>(){ 
git <span class="hljs-built_in">log</span> -3 -i --grep=<span class="hljs-string">"<span class="hljs-variable">$1</span>"</span> --pretty=format:<span class="hljs-string">'%h %s [%an]'</span>
}
</code></pre>
<p>Usage :</p>
<pre><code class="lang-bash">gsearch wip
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Reading List for 2023]]></title><description><![CDATA[The idea is to enjoy the books I plan to read. The aim is to enjoy & immerse oneself in a new world. Gaining knowledge is a nice bonus 🎁🎈🎊🎉.

Learning Typescript
Practical Pair Programming    
Dark Matter

Recursion


If you have got any book sug...]]></description><link>https://jagannath.dev/reading-list-for-2023</link><guid isPermaLink="true">https://jagannath.dev/reading-list-for-2023</guid><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Wed, 04 Jan 2023 11:35:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/91042d7314ffd940673c01b82eb43f50.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The idea is to enjoy the books I plan to read. The aim is to enjoy &amp; immerse oneself in a new world. Gaining knowledge is a nice bonus 🎁🎈🎊🎉.</p>
<ul>
<li><a target="_blank" href="https://www.learningtypescript.com/">Learning Typescript</a></li>
<li><a target="_blank" href="https://www.goodreads.com/book/show/54453243-practical-pair-programming">Practical Pair Programming</a>    </li>
<li><p><a target="_blank" href="https://www.goodreads.com/book/show/27833670-dark-matter">Dark Matter</a></p>
</li>
<li><p><a target="_blank" href="https://www.goodreads.com/book/show/42046112-recursion">Recursion</a></p>
</li>
</ul>
<p>If you have got any book suggestions tweet to me <a target="_blank" href="https://twitter.com/vaikuntj">vaikuntj</a></p>
]]></content:encoded></item><item><title><![CDATA[Enhance Your Git Skills: Mastering Cleanup and Cherry-Picking]]></title><description><![CDATA[Let's learn how to clean up and maintain your git repo

Git Clean: Cleans the working tree by recursively removing files

git clean [--dry-run]


Git CherryPick: Apply the changes introduced by some existing commits

git cherry-pick <SHA-ID>]]></description><link>https://jagannath.dev/enhance-your-git-skills-mastering-cleanup-and-cherry-picking</link><guid isPermaLink="true">https://jagannath.dev/enhance-your-git-skills-mastering-cleanup-and-cherry-picking</guid><category><![CDATA[Git]]></category><category><![CDATA[Programming Tips]]></category><category><![CDATA[developers]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Fri, 12 Aug 2022 17:26:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/KPAQpJYzH0Y/upload/v1660324962524/o7JBLXSI2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-lets-learn-how-to-clean-up-and-maintain-your-git-repo">Let's learn how to clean up and maintain your git repo</h3>
<ul>
<li><a target="_blank" href="https://git-scm.com/docs/git-clean">Git Clean</a>: Cleans the working tree by recursively removing files</li>
</ul>
<pre><code class="lang-bash">git clean [--dry-run]
</code></pre>
<ul>
<li><a target="_blank" href="https://git-scm.com/docs/git-cherry-pick">Git CherryPick</a>: Apply the changes introduced by some existing commits</li>
</ul>
<pre><code class="lang-bash">git cherry-pick &lt;SHA-ID&gt;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[My Open Source contributions]]></title><description><![CDATA[This is the list of my contributions to open source :

Docker + protractor docs
New Relic Synthetics Manager forked
Incorrect deviceName is displayed in allure reports
Outdated documentation: "Fresh browser per test"
Update docs to reflect removal of...]]></description><link>https://jagannath.dev/my-open-source-contributions</link><guid isPermaLink="true">https://jagannath.dev/my-open-source-contributions</guid><category><![CDATA[Open Source Community]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[contribute]]></category><category><![CDATA[GitHub]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Sat, 30 Jul 2022 20:09:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659246162588/y_83DaMDh.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is the list of my contributions to open source :</p>
<ul>
<li><a target="_blank" href="https://github.com/angular/protractor-cookbook/pull/9">Docker + protractor docs</a></li>
<li><a target="_blank" href="https://github.com/jags14385/new-relic-synthetics-manager">New Relic Synthetics Manager forked</a></li>
<li><a target="_blank" href="https://github.com/webdriverio/webdriverio/pull/5870">Incorrect deviceName is displayed in allure reports</a></li>
<li><a target="_blank" href="https://github.com/SeleniumHQ/seleniumhq.github.io/pull/1090">Outdated documentation: "Fresh browser per test"</a></li>
<li><a target="_blank" href="https://github.com/SeleniumHQ/seleniumhq.github.io/pull/1097">Update docs to reflect removal of find_element_by for 4.3</a></li>
<li><a target="_blank" href="https://github.com/SeleniumHQ/seleniumhq.github.io/pull/1102">Update docs to make page loading strategy more readable &amp; easy to approach</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Mastering Playwright: Running Multiple Test Tags Simultaneously]]></title><description><![CDATA[Let's consider you're managing two distinct sets of tests, each uniquely tagged — one set with @Prod-UI and the other with @PR-push, without any overlap between them.
Question: How can you execute tests from both tags using a single command?
Solution...]]></description><link>https://jagannath.dev/playwright-how-to-run-more-than-one-tag-of-tests</link><guid isPermaLink="true">https://jagannath.dev/playwright-how-to-run-more-than-one-tag-of-tests</guid><category><![CDATA[playwright]]></category><category><![CDATA[test-automation]]></category><category><![CDATA[testing tool]]></category><category><![CDATA[ci]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Tue, 26 Jul 2022 19:16:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709182488277/3635233a-9324-4929-8b36-bfd74fd43f5b.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's consider you're managing two distinct sets of tests, each uniquely tagged — one set with <code>@Prod-UI</code> and the other with <code>@PR-push</code>, without any overlap between them.</p>
<p><strong>Question:</strong> How can you execute tests from both tags using a single command?</p>
<p><strong>Solution:</strong> To run both sets of tests in a single command, one can use the following syntax:</p>
<pre><code class="lang-bash">yarn <span class="hljs-built_in">test</span>:pw --grep <span class="hljs-string">"@Prod-UI | @PR-push"</span>
</code></pre>
<p>Here's a breakdown of the command:</p>
<ul>
<li><p><code>yarn test:pw</code> initiates the test command.</p>
</li>
<li><p><code>--grep "@Prod-UI | @PR-push"</code> filters the tests to include only those with the <code>@Prod-UI</code> tag or the <code>@PR-push</code> tag.</p>
</li>
</ul>
<p>Additionally, the <code>yarn test:pw</code> command is configured as follows:</p>
<pre><code class="lang-bash">ALLURE_RESULTS_DIR=e2e/allure-results playwright <span class="hljs-built_in">test</span> e2e --headed 
--config e2e/pw.local.config.ts
</code></pre>
<p>This configuration sets the directory for Allure test results, runs the tests in a headed mode (with a visible browser), and specifies the test configuration file to use.</p>
]]></content:encoded></item><item><title><![CDATA[Using Git Better - Part 2]]></title><description><![CDATA[Let's learn how to view commit history better

A better way to view commit history
git log --pretty=format:"%h - %an, %ar : %s" -6
Time limiting the logs you see
git log --pretty=format:"%h - %an, %p %ar : %s" --since=2.weeks
git log --pretty="%h - %...]]></description><link>https://jagannath.dev/using-git-better-part-2</link><guid isPermaLink="true">https://jagannath.dev/using-git-better-part-2</guid><category><![CDATA[Git]]></category><category><![CDATA[learning]]></category><category><![CDATA[2Articles1Week]]></category><category><![CDATA[Developer]]></category><category><![CDATA[version control]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Tue, 24 May 2022 02:46:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/UT8LMo-wlyk/upload/v1653356900031/E7pRcFVyl.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Let's learn how to view commit history better</strong></p>
<blockquote>
<p>A better way to view commit history</p>
<pre><code>git <span class="hljs-keyword">log</span> --pretty=<span class="hljs-keyword">format</span>:<span class="hljs-string">"%h - %an, %ar : %s"</span> -<span class="hljs-number">6</span>
</code></pre><p>Time limiting the logs you see</p>
<pre><code>git <span class="hljs-keyword">log</span> --pretty=<span class="hljs-keyword">format</span>:<span class="hljs-string">"%h - %an, %p %ar : %s"</span> --since=<span class="hljs-number">2</span>.weeks
</code></pre><pre><code>git log <span class="hljs-operator">-</span><span class="hljs-operator">-</span>pretty<span class="hljs-operator">=</span><span class="hljs-string">"%h - %s"</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span>since<span class="hljs-operator">=</span><span class="hljs-string">"2022-01-01"</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span>before<span class="hljs-operator">=</span><span class="hljs-string">"2022-06-01"</span>
</code></pre><p>git restore is an alternative to git reset</p>
<p>Unstaging a Staged File with git restore from Git v2.23 onwards**</p>
<pre><code>git <span class="hljs-keyword">restore</span> <span class="hljs-comment">--staged README.md</span>
</code></pre></blockquote>
]]></content:encoded></item><item><title><![CDATA[How to add screenshot on failures for allure reports for WebDriverIO using Typescript]]></title><description><![CDATA[**How to add screenshot in allure reports on test failures ** Stack :

WebDriverIO

CucumberJS

TypeScript


This works with parallel test runs too.
WebdriverIO Allure Docs here
const allure = require('allure-commandline');
require('dotenv').config()...]]></description><link>https://jagannath.dev/how-to-add-screenshot-on-failures-for-allure-reports-for-webdriverio-using-typescript</link><guid isPermaLink="true">https://jagannath.dev/how-to-add-screenshot-on-failures-for-allure-reports-for-webdriverio-using-typescript</guid><category><![CDATA[webdriver]]></category><category><![CDATA[Testing]]></category><category><![CDATA[automation]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Jags]]></dc:creator><pubDate>Sat, 21 May 2022 14:06:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/P5R0NaZ6esA/upload/v1653057427120/M6MvHttCI.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>**How to add screenshot in allure reports on test failures ** Stack :</p>
<ul>
<li><p>WebDriverIO</p>
</li>
<li><p>CucumberJS</p>
</li>
<li><p>TypeScript</p>
</li>
</ul>
<p>This works with parallel test runs too.</p>
<p><a target="_blank" href="https://webdriver.io/docs/allure-reporter/#add-screenshots">WebdriverIO Allure Docs here</a></p>
<pre><code class="lang-plaintext">const allure = require('allure-commandline');
require('dotenv').config();

export const hooks = {
  afterStep: function (step, scenario, { error, duration, passed }, context) {
    if (error) {
      browser.saveScreenshot('results/allure-results/afterStepScreenshot.png');
    }
  },
  onComplete: async function () {
    const reportError = new Error('Could not generate Allure report');
    const generation = allure([
      'generate',
      'results/allure-results',
      '--clean',
      '--output',
      'results/allure-reports',
    ]);
    return new Promise&lt;void&gt;((resolve, reject) =&gt; {
      const generationTimeout = setTimeout(() =&gt; reject(reportError), 10000);

      generation.on('exit', function (exitCode) {
        clearTimeout(generationTimeout);

        if (exitCode !== 0) {
          return reject(reportError);
        }

        console.log('Allure report successfully generated');
        resolve();
      });
    });
  },
};
</code></pre>
]]></content:encoded></item></channel></rss>