<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vinay Madan</title>
    <description>The latest articles on DEV Community by Vinay Madan (@vinay_madan).</description>
    <link>https://dev.to/vinay_madan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1672733%2Fae3f422a-3058-4d13-adb0-00f1e4bdef45.png</url>
      <title>DEV Community: Vinay Madan</title>
      <link>https://dev.to/vinay_madan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vinay_madan"/>
    <language>en</language>
    <item>
      <title>import vs require in JS</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Sun, 06 Oct 2024 23:23:31 +0000</pubDate>
      <link>https://dev.to/vinay_madan/import-vs-require-in-js-4obl</link>
      <guid>https://dev.to/vinay_madan/import-vs-require-in-js-4obl</guid>
      <description>&lt;p&gt;The most common question that is asked is, What are the key differences between import vs require in Javascript?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import and Export are ES6 features(Next gen JS).&lt;/li&gt;
&lt;li&gt;Require is old school method of importing code from other files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qykuiw1fuw6yp1u49ox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9qykuiw1fuw6yp1u49ox.png" alt=" " width="577" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple image will help to you understand the differences between require and import.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Loading is synchronous(step by step) for require on the other hand import can be asynchronous&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The major difference is in &lt;code&gt;require&lt;/code&gt;, entire JS file is called or included. Even if you don't need some part of it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var myObject = require('./otherFile.js');&lt;/code&gt; //This JS file will be included fully.&lt;/p&gt;

&lt;p&gt;Whereas in import you can extract only objects/functions/variables which are required.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import { getDate }from './utils.js';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;//Here I am only pulling getDate method from the file instead of importing full file&lt;/p&gt;

&lt;p&gt;Another major difference is you can use require anywhere in the program where as import should always be at the top of file&lt;/p&gt;

&lt;p&gt;Edit: In Latest node versions you can use destructuring. It will look like this&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const { getDate } = require('./date.js');&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Playwright Annotations</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Sat, 05 Oct 2024 07:42:42 +0000</pubDate>
      <link>https://dev.to/vinay_madan/playwright-annotations-2ea3</link>
      <guid>https://dev.to/vinay_madan/playwright-annotations-2ea3</guid>
      <description>&lt;h3&gt;
  
  
  What Are Annotations in Playwright?
&lt;/h3&gt;

&lt;p&gt;Annotations are markers that you can attach to your tests to provide additional context, control test execution, or categorize tests. Playwright comes with several built-in annotations, and you can also create custom ones to suit your needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Built-in Annotations
&lt;/h3&gt;

&lt;p&gt;Playwright provides a set of built-in annotations that can be used to control the behavior of your tests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; test.skip(): Marks the test as irrelevant. Playwright will skip running this test. Use this when the test is not applicable under certain configurations.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;skip this test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This test will be skipped&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;test.fail(): Marks the test as expected to fail. Playwright will run the test and expect it to fail. If the test does not fail, Playwright will report it as an issue.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this test is expected to fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This test is expected to fail&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;test.fixme(): Marks the test as failing but will not run it. Use this for tests that are slow or have issues that prevent them from running.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;`import { test } from '@playwright/test';&lt;/p&gt;

&lt;p&gt;test.fixme('this test is not yet ready', async ({ page }) =&amp;gt; {&lt;br&gt;
  // This test will not run&lt;br&gt;
});`&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;test.slow(): Marks the test as slow, which increases the timeout duration for this test by three times.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this test is slow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This test has an extended timeout&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Focus and Skip Tests
&lt;/h3&gt;

&lt;p&gt;You can focus on specific tests or skip them based on the following conditions:&lt;/p&gt;

&lt;p&gt;Focus a Test: Run only the focused tests in the entire test suite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;focus this test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This test will be the only one executed&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Conditionally Skip a Test: Skip a test based on a condition.
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conditionally skip this test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;browserName&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;browserName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;firefox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Still working on Firefox support&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Grouping Tests
&lt;/h3&gt;

&lt;p&gt;Grouping tests allow you to organize them logically and apply hooks at the group level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Group of tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test one&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test two&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tagging Tests
&lt;/h3&gt;

&lt;p&gt;Tags help you categorize tests and run specific subsets based on these tags. Tags start with the @ symbol.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Tag a Single Test:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test login page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@fast&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Tag a Group of Tests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Group with tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@report&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test report header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test full report&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@slow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vrt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run Tests by Tag
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use the --grep option to run tests with specific tags:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;npx playwright test --grep @fast&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Skip tests with a specific tag using --grep-invert:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;npx playwright test --grep-invert @fast&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run tests containing either tag (logical OR):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;npx playwright test --grep "@fast|@slow"&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run tests containing both tags (logical AND) using regex lookaheads:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;npx playwright test --grep "(?=.*@fast)(?=.*@slow)"&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Annotating Tests
&lt;/h3&gt;

&lt;p&gt;Annotations provide more detailed context beyond tags. You can add annotations with a type and description.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotate a Single Test:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test login page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;issue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com/microsoft/playwright/issues/23180&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Annotate a Group of Tests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Annotated tests group&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;category&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;report&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test report header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test full report&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;issue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com/microsoft/playwright/issues/23180&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;performance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;very slow test!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conditional Hooks
&lt;/h3&gt;

&lt;p&gt;Use hooks like beforeEach conditionally to skip setup code based on conditions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beforeEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isMobile&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fixme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMobile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Settings page does not work in mobile yet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/settings&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Runtime Annotations
&lt;/h3&gt;

&lt;p&gt;You can also add annotations while the test is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;annotations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;browser version&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;version&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Test implementation&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Annotations in Playwright offer a flexible way to manage and categorize your tests, control their execution, and enhance reporting. By leveraging built-in annotations, tags, and custom annotations, you can tailor your testing strategy to fit your specific needs, improve test organization, and make debugging easier&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Getting started with Appium 2.0</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Wed, 07 Aug 2024 04:28:26 +0000</pubDate>
      <link>https://dev.to/vinay_madan/getting-started-with-appium-20-5acm</link>
      <guid>https://dev.to/vinay_madan/getting-started-with-appium-20-5acm</guid>
      <description>&lt;p&gt;&lt;a href="https://appium.io/docs/en/2.0/" rel="noopener noreferrer"&gt;Appium 2.0&lt;/a&gt; is a big update to the Appium framework, introducing new features. It focuses on becoming a platform with independent driver and plugin ecosystems while removing old and deprecated functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcidk49zh39yrcbcm6n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcidk49zh39yrcbcm6n6.png" alt=" " width="734" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Appium 2.0 Server Setup:&lt;br&gt;
There are two options available for installing the Appium server environment. The first method involves manually installing individual components, such as the Appium server, drivers, plugins, and appium-doctor, using separate commands.&lt;/p&gt;

&lt;p&gt;However, in this blog, we will focus on the second method, which utilizes the Appium Installer NPM Package.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This approach simplifies the installation process by guiding us through each step via the Appium CLI. You no longer need to remember specific commands, as the installer takes care of everything seamlessly and sequentially. Additionally, it automatically sets necessary environment variables, further streamlining the setup.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download the Latest Version of Node:&lt;br&gt;
Download the stable version of Node JS from its official website based on your OS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify Node and NPM Installation:&lt;br&gt;
Open the terminal and enter &lt;code&gt;“node -v”&lt;/code&gt;to check the Node.js version and “npm -v” for npm’s version. Note that npm is bundled with Node.js and should be automatically installed during the process.&lt;br&gt;
The version I used during setup might differ from the current one, as newer versions may have been released by the time you attempt the setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2my0cjdsv3ffb3srs0xp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2my0cjdsv3ffb3srs0xp.png" alt=" " width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Appium Installer Package:
Obtain the Appium installer package by executing the provided command, which installs it globally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;npm install appium-installer -g&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4slinc1385kq3qo0m380.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4slinc1385kq3qo0m380.png" alt=" " width="800" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Appium Installer and Setup:
Launch the Appium installer using the given command to access various setup options. Follow the instructions for proper setup, skipping any steps that are already completed or unnecessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdyoqnlqbzdo6z038421.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdyoqnlqbzdo6z038421.png" alt=" " width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set Up Android Environment:
Set up the Android environment, which provides essential tools and infrastructure for communication with Android devices. Choose ‘Need help setting up Android Environment to run your Appium Test’ to download the required binaries and set up environment variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4iye06m4rke52ptuni4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4iye06m4rke52ptuni4u.png" alt=" " width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set Up iOS Environment:&lt;br&gt;
Choose ‘Need help setting up iOS Environment to run your Appium Test’ to download the required binaries and set up environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select Target Devices and Browsers:&lt;br&gt;
Choose target devices for running your Appium tests, including both virtual and real devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fwlxbuz0bawj1fy399a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fwlxbuz0bawj1fy399a.png" alt=" " width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, specify the browser setup for emulators.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6fodz0lz9p0ljwuafm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6fodz0lz9p0ljwuafm6.png" alt=" " width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; Install Appium Server:
Selecting the option ‘Install Appium Server’ will download and install the latest Appium server, ensuring you have the most up-to-date version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza93g2u2oxrz4porxyhj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza93g2u2oxrz4porxyhj.png" alt=" " width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9e1tbxqwztpe1r73d43f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9e1tbxqwztpe1r73d43f.png" alt=" " width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Appium Plugins:
Opt for the ‘Install Appium Plugin’ option to view and select from a list of available Appium plugins that suit your requirements. Download the chosen plugins with a simple command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj2p78cav9rfvy66jobq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj2p78cav9rfvy66jobq.png" alt=" " width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan07o12gruvwlfz2vwgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan07o12gruvwlfz2vwgq.png" alt=" " width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Appium Doctor:
Use the ‘Run Appium Doctor’ option to verify if your Appium setup is successful and ready for running tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i1a6s4i08nlojeg56uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5i1a6s4i08nlojeg56uv.png" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download Appium Inspector:
Download Appium Inspector from the official website according to your operating system. Install the Inspector and utilize it to connect to devices (real or emulated) and inspect elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3jayehipbtmgd3crqhn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3jayehipbtmgd3crqhn.png" alt=" " width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3a800eglivbyd3ei7ov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3a800eglivbyd3ei7ov.png" alt=" " width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start Appium Server:
Run the ‘appium’ command to start the Appium server, and you are all set to begin your Appium tests with version 2.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F958t0fbwpjxh9n8qy8km.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F958t0fbwpjxh9n8qy8km.png" alt=" " width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>appium</category>
      <category>automation</category>
    </item>
    <item>
      <title>Using Localstack for Component tests</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Tue, 09 Jul 2024 01:58:03 +0000</pubDate>
      <link>https://dev.to/vinay_madan/using-localstack-for-component-tests-36b9</link>
      <guid>https://dev.to/vinay_madan/using-localstack-for-component-tests-36b9</guid>
      <description>&lt;h3&gt;
  
  
  The Ask?
&lt;/h3&gt;

&lt;p&gt;I was always wondering if I could test Cloud Services locally without the hassle and expense of provisioning cloud services using one of the providers like AWS, Azure, or GCP then I found LocalStack, an open-source project that allows us to emulate multiple AWS cloud services, such as SQS, EC2, and CloudFormation, on the local machine&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://localstack.cloud/" rel="noopener noreferrer"&gt;LocalStack&lt;/a&gt; is a cloud service emulator that runs in a single container on your laptop or in your CI environment. With LocalStack, you can run your AWS applications or Lambdas entirely on your local machine without connecting to a remote cloud provider! Whether you are testing complex CDK applications or Terraform configurations, or just beginning to learn about AWS services, LocalStack helps speed up and simplify your testing and development workflow.&lt;/p&gt;

&lt;p&gt;The required cloud service environment can be simulated using localstack and it supports wide range of cloud services including S3, lambda, SQS, SNS, SES, RDS, DynamoDB etc.&lt;/p&gt;

&lt;p&gt;Component testing allows to test the behavior of the individual components or modules separately and ensure the it’s working as expected before integrating it into a large system. In the event-driven architecture, component testing is crucial due to the complex nature of integration testing caused by its asynchronous and distributed nature. Lambda functions are responsible for handling different events. Component testing can be utilised to identify defects or issues and to verify lambda specific logics by isolating and independently testing them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pre-requisite
&lt;/h4&gt;

&lt;p&gt;There are some prerequisites to setup localstack with quarkus application.&lt;/p&gt;

&lt;p&gt;Install Docker — Localstack emulates cloud services within a single docker container. Therefore, Docker should be installed and docker daemon should be running on the machine.&lt;br&gt;
Install AWS CLI — You may need to run aws cli commands to check the cloud services created in test containers.&lt;/p&gt;
&lt;h4&gt;
  
  
  Setup
&lt;/h4&gt;

&lt;p&gt;First of all, use the below cmd to create a directory app and create index.js, docker-compose.yml, and trust-policy.json.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2hqxro4d19vc0cx1jka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2hqxro4d19vc0cx1jka.png" alt=" " width="251" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;index.js — this file is the main entry file for lambda and it contains the handler function. When the lambda function is invoked, it runs this handler method, and you will see the console statement inside your terminal. This method expects three arguments: event, context, and callback. Read more about the lambda argument here in the How it Works Section&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr05y6wbgvw9bxw8pn1q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr05y6wbgvw9bxw8pn1q.png" alt=" " width="553" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;docker-compose.yml — this file is used to start Localstack inside the docker container with some additional environments and configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz189y9jz9wle1n9y2gts.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz189y9jz9wle1n9y2gts.png" alt=" " width="486" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;trust-policy.json —this file is used to define the IAM role that grants the function permission to access resources and services. You can read more about IAM here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyl97z9s99fatq2nvkuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyl97z9s99fatq2nvkuj.png" alt=" " width="586" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You have now successfully deployed your lambda function to localstack running inside a docker container on your system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Execute the below command to invoke your lambda.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqtp558bzuveuci1t75h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqtp558bzuveuci1t75h.png" alt=" " width="606" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Switch to the terminal where you had run ‘docker-compose up’ and you will see Lambda is triggered inside your terminal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylin2mu53xqtj8qhfu50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fylin2mu53xqtj8qhfu50.png" alt=" " width="609" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations!&lt;/strong&gt; You’ve successfully invoked your lambda function and it works as it would have in the AWS console.&lt;/p&gt;

&lt;p&gt;The major upside of running localstack is that it enables you to&lt;/p&gt;

&lt;p&gt;Explore other AWS services without worrying about incurring any cost by accident&lt;br&gt;
Test your production code locally (thus crush some nasty bugs beforehand)&lt;/p&gt;

&lt;p&gt;Further we can extend it to other AWS Services such as Dynamo DB&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NodeJS Local Examples with DynamoDB/Docker&lt;/strong&gt;&lt;br&gt;
Some samples to test DynamoDB locally through Docker&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; # Download &amp;amp; Run LocalStack
  $ docker pull localstack/localstack:latest
  $ docker run -it -p 4567-4578:4567-4578 -p 8080:8080 localstack/localstack

  # Add some fake credentials locally
  $ vi ~/.aws/credentials

  # Data to include &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;
  [fake]
  region = eu-west-1
  aws_access_key_id = **NOT_REAL**
  aws_secret_access_key = **FAKE_UNUSED_CREDS**
  # Data to include &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;

  npm i aws-sdk
  node nodejs-dynamodb-create-table-local.js
  node nodejs-dynamodb-populate-table-local.js
  node nodejs-dynamodb-read-table-local.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can also view the new dynamoDB resource created at &lt;a href="http://localhost:8080/" rel="noopener noreferrer"&gt;local dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample scripts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;nodejs-dynamodb-create-table-local.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AWS = require("aws-sdk")

// URI and other properties could be load by ENV Vars or by property file (.env)
AWS.config.update({
  region: "us-west-2",
  endpoint: "http://localhost:4569"
  })

const dynamodb = new AWS.DynamoDB()

const params = {
    TableName : "Users",
    KeySchema: [{ AttributeName: "email", KeyType: "HASH"}],
    AttributeDefinitions: [{ AttributeName: "email", AttributeType: "S" }],
    ProvisionedThroughput: {
      ReadCapacityUnits: 5,
      WriteCapacityUnits: 5
    }
}

dynamodb.createTable(params, console.log)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;nodejs-dynamodb-populate-table-local.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AWS = require("aws-sdk")

// URI and other properties could be load by ENV Vars or by property file (.env)
AWS.config.update({
    region: "us-west-2",
    endpoint: "http://localhost:4569"
})

const dynamodb = new AWS.DynamoDB()

var params = {
    TableName:"Users",
    Item: {
        email : { S:"jon@doe.com"},
        fullname: { S:"Jon Doe" },
        role: { S:"Super Heroe" }
    }
};

dynamodb.putItem(params,console.log)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;nodejs-dynamodb-read-table-local.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const AWS = require("aws-sdk")

// URI and other properties could be load by ENV Vars or by property file (.env)
AWS.config.update({
    region: "us-west-2",
    endpoint: "http://localhost:4569"
})

const docClient = new AWS.DynamoDB.DocumentClient()
const email = process.env.EMAIL || 'jon@doe.com'

const params = {
    TableName: "Users",
    KeyConditionExpression: "#email = :email",
    ExpressionAttributeNames:{
        "#email": "email"
    },
    ExpressionAttributeValues: {
        ":email":email
    }
}

docClient.query(params,console.log)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>node</category>
      <category>docker</category>
      <category>localstack</category>
      <category>aws</category>
    </item>
    <item>
      <title>Difference between CommonJS and ESM modules</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Fri, 28 Jun 2024 02:37:18 +0000</pubDate>
      <link>https://dev.to/vinay_madan/difference-between-commonjs-and-esm-modules-4pff</link>
      <guid>https://dev.to/vinay_madan/difference-between-commonjs-and-esm-modules-4pff</guid>
      <description>&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;CommonJS (CJS) and ECMAScript Modules (ESM) are two different module systems in JavaScript used for organizing and structuring code. They have different syntax and behaviors, and they are often used in different contexts. Let's explore each format:&lt;/p&gt;

&lt;h4&gt;
  
  
  CommonJS (CJS):
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Synchronous: CommonJS modules are loaded synchronously. When you require a module, it is loaded and executed immediately.&lt;/li&gt;
&lt;li&gt;Server-Side: CommonJS modules were originally designed for server-side JavaScript (e.g., Node.js). They are commonly used in server-side applications and back-end development.&lt;/li&gt;
&lt;li&gt;require and module.exports: CommonJS modules use require to import modules and module.exports to export values from a module. For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Importing a module
   const someModule = require('./someModule');

   // Exporting a value
   module.exports = someValue;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;No Support for Tree Shaking: CommonJS modules don't support tree shaking, which means all exports are bundled, even if they are not used in the consuming code. This can result in larger bundle sizes in front-end applications.&lt;/li&gt;
&lt;li&gt;Dynamic Imports: CommonJS does not support dynamic imports. You cannot conditionally import modules based on runtime conditions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  ECMAScript Modules (ESM):
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Asynchronous: ESM is asynchronous. Modules are loaded and executed asynchronously, which can lead to better performance in certain scenarios.&lt;/li&gt;
&lt;li&gt;Front-End and Back-End: ESM modules are supported in both front-end (browsers) and back-end (Node.js) environments. They are becoming more widely used for front-end development.&lt;/li&gt;
&lt;li&gt;import and export Statements: ESM modules use import to import modules and export to export values from a module. For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; // Import a module
import { someValue } from './myModule';

// Export a value from a module
export default someValue;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Key Differences:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Synchronous vs. Asynchronous Loading: CommonJS modules are loaded synchronously, which means they block the execution of code until the module is loaded. ESM modules, on the other hand, are loaded asynchronously, allowing for better parallelism.&lt;/li&gt;
&lt;li&gt;Static vs. Dynamic Imports: ESM supports static imports, meaning that the import statements are resolved at compile time. CommonJS supports dynamic imports, where module paths can be constructed dynamically at runtime.&lt;/li&gt;
&lt;li&gt;Browser Compatibility: ESM is more suitable for modern web browsers, while CommonJS is often used in server-side environments. However, with the growth of JavaScript bundlers and transpilers, ESM can also be used in web applications with broader compatibility.&lt;/li&gt;
&lt;li&gt;Syntax: ESM uses import and export statements, which are more concise and align with the language's evolution. CommonJS uses require() and module.exports, which have a different syntax.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;CommonJS and ESM are two module systems in JavaScript, with CommonJS historically used in server-side environments like Node.js, and ESM emerging as the standard for modern web and server-side applications. Your choice of module system depends on your target environment and project requirements.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Design Patterns in Node.js</title>
      <dc:creator>Vinay Madan</dc:creator>
      <pubDate>Mon, 24 Jun 2024 04:09:12 +0000</pubDate>
      <link>https://dev.to/vinay_madan/design-patterns-in-nodejs-1i66</link>
      <guid>https://dev.to/vinay_madan/design-patterns-in-nodejs-1i66</guid>
      <description>&lt;p&gt;Node.js is a popular JavaScript runtime that allows developers to build scalable network applications using an event-driven, non-blocking I/O model. Like any sophisticated framework, Node.js applications can benefit from using proven design patterns to promote code reuse, maintainability and robustness. This article will provide an overview of some of the most useful design patterns for Node.js development&lt;br&gt;
Introduction to Design Patterns&lt;br&gt;
Design patterns are tried-and-true solutions to recurring problems that software developers encounter during their coding journey. They provide a structured approach to solving challenges and promote best practices in software architecture. By incorporating design patterns, developers can create more robust, maintainable, and extensible codebases.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Design Patterns Matter in Node.js
&lt;/h3&gt;

&lt;p&gt;Node.js, known for its non-blocking event-driven architecture, presents unique challenges and opportunities in software design. Applying design patterns tailored to Node.js can lead to more efficient and optimized applications. Let’s explore some key design patterns that are particularly valuable in the Node.js ecosystem:&lt;/p&gt;
&lt;h3&gt;
  
  
  Singleton Pattern
&lt;/h3&gt;

&lt;p&gt;The Singleton pattern ensures that a class has only one instance and provides a global point of access to it. In Node.js, where modules can be cached and shared across the application, using the Singleton pattern can help manage resources effectively. For instance, a database connection pool can be implemented as a singleton to prevent resource wastage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Database {
  constructor() {
    this.connection = null;
  }

  static getInstance() {
    if (!Database.instance) {
      Database.instance = new Database();
    }
    return Database.instance; 
  }

  connect() {
    // connect to database
    this.connection = 'Connected'; 
  }
}

const db1 = Database.getInstance();
const db2 = Database.getInstance();

console.log(db1 === db2); // true

db1.connect(); 

console.log(db1.connection); // 'Connected'
console.log(db2.connection); // 'Connected'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The constructor is made private to prevent direct instantiation.&lt;/li&gt;
&lt;li&gt;The static method getInstance() creates an instance if it doesn't exist yet, and returns it. This ensures only one instance is created.&lt;/li&gt;
&lt;li&gt;The instances db1 and db2 refer to the same object.&lt;/li&gt;
&lt;li&gt;When db1 connects, db2 also gets the connection because they are the same object.&lt;/li&gt;
&lt;li&gt;This ensures there is only one database instance and prevents duplicating connections. The Singleton pattern is useful for situations where only one instance of a class should exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Factory Pattern
&lt;/h3&gt;

&lt;p&gt;The Factory pattern offers a way to create objects without specifying the exact class of object that will be created. In a Node.js context, this can simplify object creation, especially when dealing with asynchronous operations such as reading files or making API calls. By abstracting object creation, the Factory pattern enhances code readability and reusability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Car {
  constructor(model, price) {
    this.model = model;
    this.price = price;
  }
}

class CarFactory {
  createCar(model) {
    switch(model) {
      case 'civic':
        return new Car('Honda Civic', 20000);
      case 'accord':  
        return new Car('Honda Accord', 25000);
      case 'odyssey':
        return new Car('Honda Odyssey', 30000);
      default:
        throw new Error('Unknown model');
    }
  }
}

const factory = new CarFactory();

const civic = factory.createCar('civic');
const accord = factory.createCar('accord');

console.log(civic.model); // Honda Civic 
console.log(accord.model); // Honda Accord
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CarFactory class handles object creation logic.&lt;/li&gt;
&lt;li&gt;The createCar() method returns a Car instance based on the model.&lt;/li&gt;
&lt;li&gt;The client code uses the factory instead of direct constructor calls.&lt;/li&gt;
&lt;li&gt;This abstracts away the object creation logic and allows easy extension of supported models. The Factory pattern is useful when there is complex object creation logic that should not be coupled to client code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Observer Pattern
&lt;/h3&gt;

&lt;p&gt;Node.js’s event-driven nature aligns well with the Observer pattern. This pattern involves a subject that maintains a list of its dependents, called observers, and notifies them of any state changes. In the context of Node.js, this can be leveraged to build event-driven systems, such as real-time applications and chat applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Subject {
  constructor() {
    this.observers = []; 
  }

  subscribe(observer) {
    this.observers.push(observer);
  }

  unsubscribe(observer) {
    this.observers = this.observers.filter(o =&amp;gt; o !== observer);
  }

  notify(data) {
    this.observers.forEach(o =&amp;gt; o.update(data));
  }
}

class Observer {
  constructor(name) {
    this.name = name;
  }

  update(data) {
    console.log(`${this.name} received ${data}`);
  }
}

const subject = new Subject();

const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');

subject.subscribe(observer1);
subject.subscribe(observer2);

subject.notify('Hello World');
// Observer 1 received Hello World 
// Observer 2 received Hello World

subject.unsubscribe(observer2);

subject.notify('Hello Again');
// Observer 1 received Hello Again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Subject maintains a list of observers.&lt;/li&gt;
&lt;li&gt;The observers subscribe and unsubscribe to the subject.&lt;/li&gt;
&lt;li&gt;When notify() is called, the subject updates all subscribed observers.&lt;/li&gt;
&lt;li&gt;This allows publishing updates to multiple objects without coupling the publisher to the subscribers. The Observer pattern is useful for event handling and asynchronous workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Middleware Pattern
&lt;/h3&gt;

&lt;p&gt;Node.js’s middleware architecture is widely used for handling requests and responses in web applications. The Middleware pattern involves a chain of functions that process a request sequentially. Each function can modify the request or response before passing it to the next function in the chain. This pattern enhances modularity and allows developers to plug in various functionalities without tightly coupling them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();

const logger = (req, res, next) =&amp;gt; {
  console.log('Logged');
  next();
}

const authenticate = (req, res, next) =&amp;gt; {
  // authenticate user 
  next(); 
}

app.use(logger); 
app.use(authenticate);

app.get('/', (req, res) =&amp;gt; {
  res.send('Hello World');
});

app.listen(3000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The middleware functions logger and authenticate wrap the route handler.&lt;/li&gt;
&lt;li&gt;They can execute logic before and after the route.&lt;/li&gt;
&lt;li&gt;The next() function passes control to the next middleware.&lt;/li&gt;
&lt;li&gt;app.use() mounts the middleware globally.&lt;/li&gt;
&lt;li&gt;This allows decomposing request handling into smaller reusable units. The middleware pattern is very common in Express and other Node.js frameworks for things like logging, authentication, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some other examples of middleware are body parsers, compression, rate limiting, and more. The pattern allows building the request pipeline in a modular fashion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Module Pattern
&lt;/h3&gt;

&lt;p&gt;The module pattern is one of the most basic but fundamental patterns in Node.js. It allows you to organize your code into separate files or modules that encapsulate specific functionality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// counter.js

let count = 0;

const increment = () =&amp;gt; {
  count++;
}

const decrement = () =&amp;gt; {
  count--;
}

const get = () =&amp;gt; {
  return count; 
}

module.exports = {
  increment,
  decrement,
  get  
};

// app.js

const counter = require('./counter');

counter.increment();
counter.increment();

console.log(counter.get()); // 2

counter.decrement();

console.log(counter.get()); // 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The module counter.js exports some functions that operate on the private count variable.&lt;/li&gt;
&lt;li&gt;The functions encapsulate the logic and data within the module.&lt;/li&gt;
&lt;li&gt;app.js imports the module and uses the public API.&lt;/li&gt;
&lt;li&gt;This pattern provides data encapsulation and only exposes a public API. The module pattern is very common in Node.js to organize code into reusable and portable modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some other examples are middleware modules, utility libraries, data access layers etc. The pattern helps manage dependencies and hide implementation details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decorator Pattern
&lt;/h3&gt;

&lt;p&gt;Decorators dynamically add new functionality to objects without affecting other instances. This is ideal for extending core modules in Node.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Car {
  constructor() {
    this.price = 10000;
  }

  getPrice() {
    return this.price;
  }
}

class CarOptions {
  constructor(car) {
    this.car = car;
  }

  addGPS() {
    this.car.price += 500;
  }

  addRims() {
    this.car.price += 300; 
  }
}

const basicCar = new Car();

console.log(basicCar.getPrice()); // 10000

const carWithOptions = new CarOptions(basicCar);

carWithOptions.addGPS();
carWithOptions.addRims();

console.log(carWithOptions.car.getPrice()); // 10800
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CarOptions wraps the Car class and extends its behavior.&lt;/li&gt;
&lt;li&gt;Methods like addGPS() modify the state of the wrapped Car.&lt;/li&gt;
&lt;li&gt;The client has a decorated instance of Car with added functionality.&lt;/li&gt;
&lt;li&gt;This allows extending behavior dynamically at runtime. The Decorator pattern is useful for abstraction and not having to subclass just to add small features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some other examples are authenticated routes, logging wrappers, caching decorators etc. The pattern provides a flexible way to adhere to the Open/Closed principle in Node.js applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Injection pattern
&lt;/h3&gt;

&lt;p&gt;Dependency injection is a pattern where modules or classes receive dependencies from an external source rather than creating them internally. It helps with decoupling, testing, and reusability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// service.js
class Service {
  constructor(db, logger) {
    this.db = db;
    this.logger = logger;
  }

  async getUser(userId) {
    const user = await this.db.findUserById(userId);
    this.logger.log(`Fetched user ${user.name}`);
    return user;
  }
}

// app.js
const Database = require('./database'); 
const Logger = require('./logger');

const db = new Database();
const logger = new Logger();

const service = new Service(db, logger);

service.getUser(1);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key points are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Service class declares dependencies via the constructor.&lt;/li&gt;
&lt;li&gt;The calling code injects the actual dependencies like db and logger.&lt;/li&gt;
&lt;li&gt;This decouples Service from concrete dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Loose coupling between modules&lt;br&gt;
Easier testing by mocking dependencies&lt;br&gt;
Ability to swap implementations&lt;br&gt;
The dependency injection pattern is commonly used with Node.js frameworks like NestJS. It enables better code organization and reusability.&lt;/p&gt;

&lt;p&gt;Promise pattern&lt;br&gt;
Promises are a pattern for asynchronous programming in Node.js. They represent the eventual result of an async operation. Here is a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fetchData = new Promise((resolve, reject) =&amp;gt; {
  // async operation
  const data = getDataFromDatabase();

  if (data) {
    resolve(data); 
  } else {  
    reject('Error fetching data');
  }
});

fetchData
  .then(data =&amp;gt; {
    // handle successful data
  })
  .catch(err =&amp;gt; {
    // handle error  
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key aspects are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Promise takes a callback with resolve and reject functions.&lt;/li&gt;
&lt;li&gt;The async operation is started inside the callback.&lt;/li&gt;
&lt;li&gt;resolve(data) returns the data on success.&lt;/li&gt;
&lt;li&gt;reject(error) returns the error on failure.&lt;/li&gt;
&lt;li&gt;Consumers use .then() and .catch() to get the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Avoid callback hell in async code&lt;/strong&gt;&lt;br&gt;
Standardized way to handle async results&lt;br&gt;
Ability to chain and compose promises&lt;br&gt;
Promises are integral to modern Node.js development and enable writing clean asynchronous code. They power libraries like axios, core APIs like fs.promises, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing Design Patterns&lt;/strong&gt;&lt;br&gt;
Now that we’ve explored some key design patterns that align with Node.js’s strengths, let’s dive into how to implement them effectively:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Understanding Context&lt;br&gt;
Before applying any design pattern, it’s crucial to understand the context of your application. Consider factors such as the application’s requirements, scalability needs, and the specific challenges you’re trying to address. Design patterns are not one-size-fits-all solutions; they should be tailored to fit the unique characteristics of your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modularization&lt;br&gt;
Node.js encourages modularization through its module system. When implementing design patterns, strive to keep modules small, focused, and single-responsibility. This promotes code reusability and maintainability, making it easier to swap out or enhance specific functionalities without affecting the entire application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous Patterns&lt;br&gt;
Given Node.js’s asynchronous nature, it’s essential to choose design patterns that align with asynchronous programming paradigms. Patterns like the Observer pattern and the Middleware pattern naturally fit into the asynchronous environment, allowing developers to handle events and asynchronous operations seamlessly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Design patterns enable Node.js developers to write organized, flexible and robust code. Leveraging proven patterns like factories, decorators and singletons allows you to build large-scale applications that are easy to maintain and extend over time. Understanding how to apply design principles is key for mastering advanced Node development.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>designpatterns</category>
    </item>
  </channel>
</rss>
