<?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: Stipe</title>
    <description>The latest articles on DEV Community by Stipe (@st1p3kolovrat).</description>
    <link>https://dev.to/st1p3kolovrat</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1145993%2F8fa395a2-ef83-45d9-8d89-d99abf4d3839.png</url>
      <title>DEV Community: Stipe</title>
      <link>https://dev.to/st1p3kolovrat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/st1p3kolovrat"/>
    <language>en</language>
    <item>
      <title>Mobilewright Part 2: From The First Test to a Real Test Suite</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Tue, 06 Oct 2026 18:32:59 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/mobilewright-part-2-from-the-first-test-to-a-real-test-suite-229d</link>
      <guid>https://dev.to/st1p3kolovrat/mobilewright-part-2-from-the-first-test-to-a-real-test-suite-229d</guid>
      <description>&lt;p&gt;You've written your first Mobilewright test. Now let's grow it into a suite that's organized, readable and ready to run on real devices.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/st1p3kolovrat/mobilewright-sleeping-giant-if-you-know-playwright-you-already-know-mobile-testing-5455"&gt;Part 1&lt;/a&gt; we covered what Mobilewright is, why it feels so familiar if you know Playwright.&lt;/p&gt;

&lt;p&gt;One basic test isn't a test suite. What happens when you have 10 tests? 50? Several screens, several devices, and a teammate who wants to add tests too?&lt;/p&gt;

&lt;p&gt;In this post I will take that single test and grow it, step by step, into something you would be proud to hand over to your team. As before, there is very little code: this is about &lt;strong&gt;how to think&lt;/strong&gt; about structure, not memorizing syntax.&lt;/p&gt;




&lt;h2&gt;
  
  
  How your very first test might have looked like
&lt;/h2&gt;

&lt;p&gt;Your first test looked roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;user can log in&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;screen&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;demo&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;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bigs3cret&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;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Log in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;p&gt;It works. But imagine 20 tests that all start by logging in. If the login button gets a new test ID or name. You'd be fixing the same line in 20 places.&lt;/p&gt;

&lt;p&gt;That's the first problem we'll solve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Give every screen its own home (Screen Objects)
&lt;/h2&gt;

&lt;p&gt;In web testing with Playwright, you have probably heard of &lt;strong&gt;Page Objects&lt;/strong&gt;. In mobile testing, the same idea is usually called &lt;strong&gt;Screen Objects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One class per app screen. It knows where the buttons are and what you can do on that screen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So instead of tests that talk about test IDs and buttons, you get tests that talk about &lt;strong&gt;what the user does&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;user can log in&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;loginScreen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;homeScreen&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;loginScreen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;demo&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;secret&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;homeScreen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;welcomeMessage&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;p&gt;That reads almost like English. And when the login button changes, you update &lt;strong&gt;one file&lt;/strong&gt;, the Login screen class, and every test is fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beginner tip:&lt;/strong&gt; start with a small base class that every screen extends. It's a handy place for things all screens share, such as "am I on Android or iOS?"&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Let fixtures do the setup for you
&lt;/h2&gt;

&lt;p&gt;Did you notice &lt;code&gt;loginScreen&lt;/code&gt; and &lt;code&gt;homeScreen&lt;/code&gt; in the test above? We didn't create them with &lt;code&gt;new LoginScreen(...)&lt;/code&gt;. They just appeared.&lt;/p&gt;

&lt;p&gt;That's a &lt;strong&gt;fixture&lt;/strong&gt;, one of Playwright's best features, and Mobilewright has it too.&lt;/p&gt;

&lt;p&gt;A fixture is a way of saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Whenever a test asks for &lt;code&gt;loginScreen&lt;/code&gt;, build one and hand it over."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You define it once, and every test can simply ask for what it needs. Your tests stay short and focused on behavior, and all the setup lives in one place.&lt;/p&gt;

&lt;p&gt;If you've used Playwright's &lt;code&gt;page&lt;/code&gt; fixture, you've already used this pattern. You're now just making your own.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: One config, many devices
&lt;/h2&gt;

&lt;p&gt;Here is where mobile starts to feel different from web, and where &lt;a href="https://mobilewright.dev/docs/" rel="noopener noreferrer"&gt;Mobilewright&lt;/a&gt; shines.&lt;/p&gt;

&lt;p&gt;On the web, Playwright &lt;strong&gt;projects&lt;/strong&gt; let you run the same tests on Chrome, Firefox and Safari. In Mobilewright, &lt;strong&gt;projects are devices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Pixel emulator&lt;/li&gt;
&lt;li&gt;an iPhone simulator&lt;/li&gt;
&lt;li&gt;a real Samsung phone in the cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You list your devices once in the config, and then choose which one to run on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mobilewright &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Pixel 8"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A nice pattern I recommend is keeping the device list in a small separate file (JSON works well). Then adding a new device means adding one line, not editing your config logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Same tests, laptop or cloud
&lt;/h2&gt;

&lt;p&gt;In Part 1 I mentioned that you can start locally and move to real devices later. Here is how that looks in practice.&lt;/p&gt;

&lt;p&gt;Your config can check one environment variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No cloud key set&lt;/strong&gt; → use the local driver and your emulator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud key set&lt;/strong&gt; → use real devices from a device farm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your tests don't change at all. Only &lt;strong&gt;where&lt;/strong&gt; they run changes.&lt;/p&gt;

&lt;p&gt;This is great for teams: developers run tests on their own emulators during the day, and the pipeline runs the same tests on real phones every night.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beginner tip:&lt;/strong&gt; when running locally, make sure that cloud key is empty. Otherwise you might accidentally book a cloud device when you only wanted your emulator.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Write tests your whole team can read (BDD)
&lt;/h2&gt;

&lt;p&gt;Once your suite grows, you will have people asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What exactly do our mobile tests check?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reading TypeScript isn't fun for everyone. That's where &lt;strong&gt;BDD (Behavior-Driven Development)&lt;/strong&gt; comes in. You describe tests in plain language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gherkin"&gt;&lt;code&gt;&lt;span class="kn"&gt;Scenario&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; User logs in with valid credentials
  &lt;span class="nf"&gt;Given &lt;/span&gt;the app is open on the login screen
  &lt;span class="nf"&gt;When &lt;/span&gt;the user logs in with valid credentials
  &lt;span class="nf"&gt;Then &lt;/span&gt;the home screen is displayed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each line is connected to a small piece of code (a "step"), and those steps use your Screen Objects from Step 1. Everything you've built so far fits together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Feature file → Steps → Screen Objects → Mobilewright&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Product owners can read the feature files, testers can write new scenarios by reusing existing steps, and the automation runs underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Stop preparing data through the app
&lt;/h2&gt;

&lt;p&gt;This is the lesson that saved me the most time.&lt;/p&gt;

&lt;p&gt;Say a test needs a brand-new user. The tempting approach is to tap through the sign-up screens at the start of every test. Don't. It's slow, it's flaky, and if sign-up breaks, &lt;strong&gt;every&lt;/strong&gt; test fails, even ones that have nothing to do with sign-up.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create test data with API calls&lt;/strong&gt; before the test (in a "before" hook)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean up with API calls&lt;/strong&gt; after the test (in an "after" hook)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the app's UI only for what you're actually testing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your tests get faster and more stable, and when something fails you know exactly where the problem is.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Every test starts fresh
&lt;/h2&gt;

&lt;p&gt;This one sounds obvious, but it's easy to forget.&lt;/p&gt;

&lt;p&gt;If test A logs in and test B silently relies on already being logged in, you have created a hidden dependency. Which is path to flaky test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt; Every test should start from a clean app, as if it were just installed. Yes, it costs a few seconds per test. It saves hours of debugging failed tests. &lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Learn to read failures
&lt;/h2&gt;

&lt;p&gt;As your suite grows, failures happen. That's normal, and it's the whole point of testing!&lt;/p&gt;

&lt;p&gt;Mobilewright gives you good tools here, just like Playwright:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The HTML report&lt;/strong&gt; shows each step, how long it took, and where it failed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The UI tree on failure&lt;/strong&gt; is a snapshot of everything that was on screen when the test broke (switch it on in the config)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mobilewright doctor&lt;/code&gt;&lt;/strong&gt; is still your friend whenever something about the environment feels off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few things that might save you time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A locator found the wrong element.&lt;/strong&gt; For example, searching for the text "Login" matched the screen title instead of the button. Be specific: prefer test IDs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobilewright doesn't complain about duplicates.&lt;/strong&gt; Playwright on the web fails when a locator matches two elements. Mobile can quietly pick the first one. Another reason to use unique test IDs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A button said it was disabled when it wasn't.&lt;/strong&gt; Some apps report a button as disabled while the keyboard is open. Check what the user actually sees, not only the button's state.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 9: Run it automatically (CI)
&lt;/h2&gt;

&lt;p&gt;Now that your suite is organized, the last step is making it run without you.&lt;/p&gt;

&lt;p&gt;Since it is "just" a Node.js project with a test command, you can run it in any CI system, such as GitHub Actions, GitLab CI or others. The typical setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install dependencies&lt;/li&gt;
&lt;li&gt;Get the app build (APK or iOS app)&lt;/li&gt;
&lt;li&gt;Run the tests against cloud devices (no emulator needed on the CI machine)&lt;/li&gt;
&lt;li&gt;Save the HTML report as a build artifact so anyone can open it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember Step 4? That's why it matters. The tests that run in CI are the exact same tests you run on your laptop.&lt;/p&gt;




&lt;h2&gt;
  
  
  What your project looks like now
&lt;/h2&gt;

&lt;p&gt;Let's zoom out. We started with one test file. Now we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/      → plain-language scenarios (BDD)
steps/         → glue between scenarios and screens
screens/       → one class per app screen
fixtures/      → setup that tests can ask for
api/           → test data creation and cleanup
devices.json   → which devices we run on
mobilewright.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every folder has one clear job. A new teammate can open the project and understand it in minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Going from one test to a real suite comes down to a few ideas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Screen Objects&lt;/strong&gt; keep locators in one place&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixtures&lt;/strong&gt; keep setup out of your tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Projects = devices&lt;/strong&gt;, so one test runs anywhere&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BDD&lt;/strong&gt; makes tests readable for the whole team&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs prepare test data&lt;/strong&gt;, the UI is only for testing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Every test starts fresh&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reports and UI trees&lt;/strong&gt; explain failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI&lt;/strong&gt; runs it all for you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And the best part? Almost every one of these ideas comes straight from Playwright. If you learned it for web, you already know it for mobile.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;How is your mobile test suite organized? Do you use Screen Objects, BDD, or something else entirely? Tell me in the comments!&lt;/em&gt; 👇&lt;/p&gt;

</description>
      <category>mobilewright</category>
      <category>playwright</category>
      <category>mobiletesting</category>
      <category>qa</category>
    </item>
    <item>
      <title>Mobilewright Part 1: Sleeping Giant: If You Know Playwright, You Already Know Mobile Testing</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Tue, 29 Sep 2026 18:03:59 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/mobilewright-sleeping-giant-if-you-know-playwright-you-already-know-mobile-testing-5455</link>
      <guid>https://dev.to/st1p3kolovrat/mobilewright-sleeping-giant-if-you-know-playwright-you-already-know-mobile-testing-5455</guid>
      <description>&lt;p&gt;A beginner-friendly introduction to Mobilewright: what it is, why it's great, and how closely it resembles Playwright.&lt;/p&gt;




&lt;p&gt;Mobile test automation has a reputation for being painful. You install lots of tools, run servers in the background, wait on things by hand, and get tests that fail for no clear reason.&lt;/p&gt;

&lt;p&gt;If you used &lt;strong&gt;Playwright&lt;/strong&gt; for web testing, you know it doesn't have to be that way. The good news is that the same experience now exists for mobile apps. It's called &lt;strong&gt;Mobilewright&lt;/strong&gt;. Oh yes!!&lt;/p&gt;

&lt;p&gt;In this post I'll explain what Mobilewright is, why I like it, and how closely it resembles Playwright. You don't need any mobile testing experience to follow along.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Mobilewright?
&lt;/h2&gt;

&lt;p&gt;Mobilewright is an open-source framework for writing automated tests for &lt;strong&gt;Android and iOS apps&lt;/strong&gt;. It lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your app on an emulator, a simulator or a real phone&lt;/li&gt;
&lt;li&gt;Find things on the screen (buttons, text fields, labels)&lt;/li&gt;
&lt;li&gt;Tap, type, swipe and scroll&lt;/li&gt;
&lt;li&gt;Check that the app shows what it should&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, it's &lt;strong&gt;Playwright, but for phones&lt;/strong&gt;. Its authors designed it to feel the same: the same way of writing tests, the same kind of commands, and the same reports.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why QAs will love it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Setup is short
&lt;/h3&gt;

&lt;p&gt;Traditional mobile automation often means setting up a separate automation server, drivers and a lot of configuration before your first test runs.&lt;/p&gt;

&lt;p&gt;With Mobilewright you install a package, run one command to check your setup (&lt;code&gt;mobilewright doctor&lt;/code&gt;), and you're ready. That command tells you what is missing and what to fix, so you are not left guessing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. It waits for you
&lt;/h3&gt;

&lt;p&gt;The most common beginner mistake in UI testing is adding "sleep 5 seconds" everywhere and hoping the app has loaded.&lt;/p&gt;

&lt;p&gt;Like Playwright, Mobilewright &lt;strong&gt;waits automatically&lt;/strong&gt;. When you say "tap this button", it waits until the button appears. When you say "expect this text to be visible", it keeps checking until the text shows up or a timeout runs out. Your tests get faster and less flaky without extra effort from you.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. One test can cover Android and iOS
&lt;/h3&gt;

&lt;p&gt;You write the test once and choose which device to run it on. The same test can run on an Android emulator today and an iPhone simulator tomorrow. Important to note is you can use same element locator for both Android and iOS, which is not the case with other frameworks.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Local first, cloud when you need it
&lt;/h3&gt;

&lt;p&gt;You can start on your laptop with a free emulator. When you are ready, the same tests can run on &lt;strong&gt;real devices in the cloud&lt;/strong&gt;, usually by changing one setting and not your tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Reports that show what went wrong
&lt;/h3&gt;

&lt;p&gt;When a test fails, you get an HTML report that shows which step failed, the error, and a snapshot of what was on the screen. Debugging turns into reading the report instead of guessing.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Mobilewright resembles Playwright
&lt;/h2&gt;

&lt;p&gt;This is what makes it so easy to learn. If you know Playwright, here's how the concepts map:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Playwright (web)&lt;/th&gt;
&lt;th&gt;Mobilewright (mobile)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;page&lt;/code&gt;: the browser tab&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;screen&lt;/code&gt;: the phone screen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;browser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;device&lt;/code&gt;: the phone itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;getByRole&lt;/code&gt;, &lt;code&gt;getByText&lt;/code&gt;, &lt;code&gt;getByTestId&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Same locator methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;click()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tap()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fill()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;fill()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;expect(...).toBeVisible()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;expect(...).toBeVisible()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;playwright.config.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mobilewright.config.ts&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Projects = browsers&lt;/td&gt;
&lt;td&gt;Projects = devices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npx playwright test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx mobilewright test&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npx playwright show-report&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npx mobilewright show-report&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fixtures and Page Objects&lt;/td&gt;
&lt;td&gt;Fixtures and Screen Objects&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here's one small example so you can see it for yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Playwright (web):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;user can log in&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="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;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;demo&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;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bigs3cret!&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;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Log in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&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="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;p&gt;&lt;strong&gt;Mobilewright (mobile):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;user can log in&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;screen&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;demo&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;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bigs3cret!&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;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Log in&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;p&gt;That's the whole difference: &lt;code&gt;page&lt;/code&gt; becomes &lt;code&gt;screen&lt;/code&gt; and &lt;code&gt;click&lt;/code&gt; becomes &lt;code&gt;tap&lt;/code&gt;. Everything else carries over, including your habits, your project structure and your team's existing Playwright knowledge.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beginner tips from my experience
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ask developers for test IDs.&lt;/strong&gt; The most reliable way to find an element is a stable ID that the app developers add for testing. It's a small request that makes every test more stable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the Page Object pattern from day one.&lt;/strong&gt; Create one class per app screen (for example a Login screen or a Home screen) that holds its buttons and actions. Your tests then read like plain English, and when the UI changes you update one file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep tests independent.&lt;/strong&gt; Start every test from a fresh app state. If one test depends on another, a single failure spreads through the whole suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prepare data outside the app.&lt;/strong&gt; If a test needs a user account, create it with an API call, not by tapping through sign-up screens. Save the UI steps for what you actually want to test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pin your versions.&lt;/strong&gt; Mobilewright is young and improves quickly. That's exciting, but pin your versions so an update doesn't surprise you in the middle of a sprint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the failure report before changing code.&lt;/strong&gt; The screen snapshot in the report usually tells you exactly what went wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: it works well with BDD
&lt;/h2&gt;

&lt;p&gt;If your team likes writing tests in plain language (Given / When / Then), Mobilewright works with Gherkin feature files through Playwright's BDD tooling. Product owners and testers can read the scenarios, and the automation runs underneath.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;For years, mobile testing felt like a different, more difficult world than web testing. Mobilewright closes that gap. If you can write a Playwright test, you can write a mobile test.&lt;/p&gt;

&lt;p&gt;Install it, run &lt;code&gt;doctor&lt;/code&gt;, write one test for your login screen, and watch it run on a phone. That first green test is very satisfying. 📱✅&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you tried testing mobile apps yet? What was the hardest part for you? Let me know in the comments!&lt;/em&gt; 👇&lt;/p&gt;

</description>
      <category>mobiletesting</category>
      <category>testing</category>
      <category>playwright</category>
      <category>mobilewright</category>
    </item>
    <item>
      <title>Epoch - Ethereum 2.0</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Mon, 10 Jun 2024 15:44:28 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/epoch-ethereum-20-k9f</link>
      <guid>https://dev.to/st1p3kolovrat/epoch-ethereum-20-k9f</guid>
      <description>&lt;p&gt;Greetings!! This is the first article that I plan to publish about random things Ethereum 2.0. In this article boss of the hour is Epoch. You will find out what is epoch in Ethereum 2.0 proof of stake, and what role does it play. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ethereum Epoch is a time frame during a set of validators activities are happening.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Activities:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validators propose blocks&lt;/li&gt;
&lt;li&gt;Validators attest blocks proposed by others&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each epoch is divided into smaller time units, called &lt;strong&gt;slots&lt;/strong&gt;. One epoch has 32 slots. Each slot lasts 12 seconds. Meaning each epoch lasts approximately 6.4 minutes. &lt;br&gt;
One epoch therefore will have 32 blocks, and each slot will have one block. &lt;/p&gt;

&lt;p&gt;In each slot there is one validator that is assigned to propose a new block, and a committee of validators that attest validity of that block.  &lt;/p&gt;




&lt;p&gt;Imagine a hotel named "The Grand Ethereum hotel". Each night, the hotel's kitchen team of chefs works together in a organised way to prepare a set of dishes for buffet dinner for hotel guests. Kitchen operates on a precise schedule to ensure fairness, efficiency, and culinary excellence.&lt;/p&gt;

&lt;p&gt;Let us imagine one epoch is one night, or one dinner service. Therefore each epoch represents one dinner service over entire year.&lt;/p&gt;

&lt;p&gt;For each slot, a team of chefs is involved. Among them, one chef is randomly chosen to be the Lead Chef for that slot. Selection process is fair, unpredictable and random, ensuring every chef has the opportunity to lead. &lt;/p&gt;

&lt;p&gt;The chosen Lead Chef for that slot is responsible for making key decisions, coordinating the team's actions, and creating a dish (proposing a block).&lt;/p&gt;

&lt;p&gt;Supporting Chefs' Role: The other chefs act as committee (attesting validators). They assist the Lead Chef by checking and supporting their decisions and actions, making sure everything is cooked perfectly. They attest the dish before it is given to hotel guests.  &lt;/p&gt;




&lt;p&gt;To summarise once again, In Ethereum 2.0, epoch consists of maximum 32 blocks. This means every epoch is composed of 32 slots, with each slot potentially holding one block. Slots occur every 12 seconds, making each epoch approximately 6.4 minutes long. Validators work within these epochs to propose and attest to blocks, ensuring the security and consensus of the network.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>proofofstake</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Distributed validator technology with Obol Labs</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Thu, 30 May 2024 10:35:51 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/distributed-validator-technology-with-obol-labs-4d38</link>
      <guid>https://dev.to/st1p3kolovrat/distributed-validator-technology-with-obol-labs-4d38</guid>
      <description>&lt;p&gt;Recently I was reading about &lt;a href="https://docs.obol.tech/docs/int/Overview" rel="noopener noreferrer"&gt;Obol Labs&lt;/a&gt; and found intriguing what they are offering to the world. If you are into proof of stake I think you should read this one and check out their official &lt;a href="https://docs.obol.tech/docs/int/Overview" rel="noopener noreferrer"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Obol team is working on Distributed Validator Technology. Their mission is to preserve decentralization, make validators more fault-tolerant, and even give opportunity for smaller individuals to participate as validator. &lt;/p&gt;

&lt;p&gt;Quote from their documentation: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Obol Network will become an open, community governed, self-sustaining project over the coming months and years. Together we will incentivize, build, and maintain distributed validator technology that makes public networks a more secure and resilient foundation to build on top of.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;One word is enough. Beautiful.&lt;/p&gt;

&lt;p&gt;If you are familiar with Ethereum 2.0, in proof of stake validators get punished for malicious activity. But sometimes validators get penalty without malicious intent. It can happen due to errors or misconfiguration. For example you can have 2 nodes and by mistake use same validator key on both, which would result in double voting or double proposing. Or your validator goes offline for longer than allowed, will result in inactivity penalty. Obol jumps to solve this as well. Lets find out how.  &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%2F1a5nv5cev77ar8l6mcol.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%2F1a5nv5cev77ar8l6mcol.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;DVT&lt;/strong&gt; - Distributed Validator Technology is a Ethereum proof of stake validator that consists of multiple entities forming one validator. Not all validators need to be online 100% of the time in order to continue participating in the network. More info on that in &lt;a href="https://docs.obol.tech/docs/charon/cluster-configuration#cluster-size-and-resilience" rel="noopener noreferrer"&gt;here&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Charon&lt;/strong&gt; is a distributed validator client designed to work as part of the Ethereum proof-of-stake protocol. It forms a cluster of nodes that collectively act as a single validator. Meaning they allow multiple entities to join into one group and act as one validator in Ethereum network. &lt;/p&gt;

&lt;p&gt;Each node in the cluster is responsible for contributing to the validation process, ensuring high availability and fault tolerance.&lt;/p&gt;

&lt;p&gt;Traditionally when you were setting up a node you needed to generate public/private key. Now you probably are already wondering, how will multiple entities who have joined to form one validator keep this trustless. Solution is called &lt;code&gt;key sharing&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Entities who agreed to form a group and act as one validator, will collaboratively generate and share a distributed key without any single participant knowing the complete key. This process enhances security and fault tolerance for operating distributed validators by ensuring that no individual entity holds complete control over the key. You can find out more in official &lt;a href="https://docs.obol.tech/docs/charon/dkg" rel="noopener noreferrer"&gt;docs&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Benefits of Using Charon
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Resiliency:&lt;/strong&gt; The distributed nature ensures that validator operations continue even if some nodes go offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security:&lt;/strong&gt; Distributed shared key mechanism enhances the security of the staking process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decentralization:&lt;/strong&gt; Helps broader goal of Ethereum’s decentralization by enabling more participants to run validators in distributed way.&lt;/p&gt;

&lt;p&gt;Setting up Charon involves coordination and careful configuration but results in a robust and secure validation setup for Ethereum staking. For more detailed steps and technical specifics, refer to the Charon documentation provided by &lt;a href="https://docs.obol.tech/docs/int/Overview" rel="noopener noreferrer"&gt;Obol Labs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>proofofstake</category>
    </item>
    <item>
      <title>Testing Pyramid</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Sun, 19 May 2024 12:19:40 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/testing-pyramid-2bj0</link>
      <guid>https://dev.to/st1p3kolovrat/testing-pyramid-2bj0</guid>
      <description>&lt;p&gt;Hey developers and CEOs, this article is for you. &lt;/p&gt;

&lt;p&gt;Im going to explain you five different types of software testing that you need to know as a software developer or a CEO of an IT company. &lt;/p&gt;

&lt;p&gt;You have probably heard of the testing pyramid. Chances are you probably haven't thought much about why the pyramid is a pyramid to start off with. &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%2Fetpkgi7wa4kljweonjhf.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%2Fetpkgi7wa4kljweonjhf.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  Unit Tests
&lt;/h4&gt;

&lt;p&gt;Tests at the bottom of the pyramid should make up the majority of the tests in your test suite. This is where you should be focusing most of your efforts on. As we move up the pyramid, the tests become more complex and slower and they take more time to maintain. At the base of our pyramid, we have the unit tests. &lt;br&gt;
Now, most developers are aware of what unit tests are and the importance of them. Developers are the one who are writing unit tests and they are responsible for that part of quality assurance. Developer writes unit tests for all the methods and functions in the code, to ensure that the program is working correctly at the lowest level. &lt;br&gt;
You may wonder on the number of unit tests you have to write. That really depends on what the goal is for your testing strategy. You should aim for and test every single line of your code in your methods. If for some reason something is preventing you, then that should be a sign that your function is doing too much or you haven't written it with testability in mind. &lt;br&gt;
100% testing coverage means to have test coverage of every single line of code.&lt;/p&gt;

&lt;p&gt;Unit tests are not enough to ensure that your software is working and looking as expected. You should not assume anything if it is working at the lowest level, that it's all going to work when you put it together. That is often not the case. For that reason we introduce next level of testing in the testing pyramid. &lt;/p&gt;




&lt;h4&gt;
  
  
  API Automated Tests
&lt;/h4&gt;

&lt;p&gt;The next level up in our testing pyramid is what we call API tests. &lt;br&gt;
This is where we test each endpoint in isolation, to cover expected and unexpected behaviour. Error messages, response body, json schema, http status codes, etc. &lt;br&gt;
API tests are very fast, and we should when scenario allows us aim for writing end to end tests. To ensure that feature workflows are working exactly as we expect them.  &lt;/p&gt;

&lt;p&gt;You would run them in dev environment which should be a mirror of your prod environment. &lt;/p&gt;

&lt;p&gt;Unit tests and API tests are all generally run as part of the build process, before a release, after each git push to your working branch, after each git push to master branch or you have them scheduled to run at certain time. Depending on how your process is defined. &lt;/p&gt;




&lt;h4&gt;
  
  
  Frontend Automated Tests
&lt;/h4&gt;

&lt;p&gt;If you're writing a web application, then these will typically be in the form of automated UI tests. &lt;br&gt;
And we generally use tools such as selenium, playwright and such, to mimic user action in the UI through a web browser. The goal here is to test that everything is working as expected end-to-end, is clickable, typeable and such. These tests typically include a mix between &lt;strong&gt;functional testing&lt;/strong&gt;, such as making sure that you can signup/login or a form is populated correctly, And &lt;strong&gt;acceptance testing&lt;/strong&gt;, which makes sure that your application is meeting business requirements. I tend to write end-to-end tests in style what is called a Gherkin language, which follows the given-when-then pattern. Frameworks such as Cucumber or any other BDD framework allow us to execute code in this format while still having the tests non-technical-human-eye-readable. &lt;br&gt;
These type of tests are significantly slower than unit and API tests and can take really really really long time to run, and typically they're not run on every single git push. Imagine you have hundreds of these tests, they can take several hours to run, so you generally need to run them overnight. &lt;/p&gt;

&lt;p&gt;Frontend automated tests are not ideal if you want to be releasing very often in a startup style. Most QA teams split up their tests into multiple groups tagging scenarios by critical group that they can run before each deployment. &lt;br&gt;
For example, most essential tests can be tagged as &lt;code&gt;@smoke&lt;/code&gt; and you can setup to run only subset of those tests tagged with that tag after given action. This would save you time, and you would run only what you need. While full suite of tests you could schedule overnight. &lt;/p&gt;

&lt;p&gt;It is important to note that these tests need all the components working together, and therefore they're typically run on an environment such as QA or UAT. It can take a while to have a stable set of end-to-end tests. Subtle things such as your application taking a little longer to load, or someone accidentally breaking QA or UAT environment can cause your tests to break, and therefore you generally need someone working full time on your automation tests. Maintenance is absolutely crucial, in both API and Frontend tests. Especially in Frontend tests, as they are most dependent and most fragile. &lt;/p&gt;




&lt;h4&gt;
  
  
  Manual Tests
&lt;/h4&gt;

&lt;p&gt;As cherry on top of our pyramid, we have manual tests. These are the tests that either need human eye, human exploratory mind, or they are not worth the time in trying to automate them. Manual testing even though unfairly not respected enough play important part in the last final piece of functional and visual side of the software application. &lt;/p&gt;

&lt;p&gt;There are certain bugs you can only find by executing manual testing. &lt;br&gt;
Manual testing should be executed in various phases. While feature is developing, you want to test new things, but you also want to make sure you are executing entire suite of tests you have from before, to ensure that new code did not break existing features. That is also called regression testing. &lt;/p&gt;

&lt;p&gt;When you find a bug in your application, it is always better to find it lower down the pyramid than near the top. Each bug found in manual testing phase makes you to run application, reproduce the issue and search for logs and try and work out where exactly your application failed. Compare that to finding a bug in your unit tests and you will be given a stack trace that shows you the exact line where the problem occurred. &lt;/p&gt;

</description>
      <category>testing</category>
      <category>api</category>
      <category>unittest</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Testing is...</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Thu, 16 May 2024 09:54:10 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/testing-is-9h2</link>
      <guid>https://dev.to/st1p3kolovrat/testing-is-9h2</guid>
      <description>&lt;p&gt;Testing involves conducting a variety of experiments to understand the product's actual behaviour, capabilities, and limitations, revealing insights beyond initial expectations or documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing is:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Ensure everything works as expected&lt;/li&gt;
&lt;li&gt;Identifying potential risks&lt;/li&gt;
&lt;li&gt;Uncover edge cases&lt;/li&gt;
&lt;li&gt;Promote culture of quality&lt;/li&gt;
&lt;li&gt;Be the client (Put yourself in shoes of clients)&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;The main objective of testing is to uncover risks that could affect the product's success, including vulnerabilities, performance issues, and other factors that might lead to failures in production.&lt;/p&gt;

&lt;p&gt;When we talk about edge cases, there are testers that will seem efficient in the eyes of project managers but they will never add extra layer that might cover potential risk. Testing seeks to find those rare but critical scenarios that occur at the extremes, they cover what can happen in rare situation. Rare does not mean less risky. One "hole" can be very expensive if discovered in production. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testing is not:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Just writing test plan and test cases&lt;/li&gt;
&lt;li&gt;Only finding and reporting bugs&lt;/li&gt;
&lt;li&gt;Automate every single thing&lt;/li&gt;
&lt;li&gt;One time thing&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;While documenting test plan and test cases is necessary, effective testing goes beyond this, requiring critical thinking, creativity, and adaptability to new information and evolving requirements.&lt;/p&gt;

&lt;p&gt;Testing isn't about assigning blame for defects. It's a collaborative effort to improve the product. A blame-free environment encourages open communication and teamwork, which are crucial for successful testing and quality assurance.&lt;/p&gt;

&lt;p&gt;Having automated tests is a super useful, but it cannot replace exploratory testing and human judgment. Some scenarios necessitate manual testing to uncover issues that automated scripts might miss.&lt;/p&gt;

&lt;p&gt;Testing should be integrated into every phase of development, from initial design to post-release maintenance. It’s not just a final checkpoint but an non-stop process contributing to the product's continuous evolution and standard of quality.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>softwaretester</category>
      <category>qualityassurance</category>
    </item>
    <item>
      <title>The Graph Demystified - Fetching Data From The Limitless Blockchain Bookshelves</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Wed, 13 Mar 2024 14:45:32 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/the-graph-demystified-fetching-data-from-the-limitless-blockchain-bookshelves-4hja</link>
      <guid>https://dev.to/st1p3kolovrat/the-graph-demystified-fetching-data-from-the-limitless-blockchain-bookshelves-4hja</guid>
      <description>&lt;p&gt;As a curious man I was reading about the graph protocol. Since I am not a blockchain developer I wasn't aware of challenges when you are in need of grabbing certain data from a particular location on the blockchain. I found it interesting how Graph works and I think it is a good idea to share with others what I have learned and how I understood it. So let's get started. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard definition:&lt;/strong&gt; &lt;br&gt;
The Graph enables indexing and querying of data from various blockchains. It facilitates efficient and performant access to complex data sets, such as those from smart contracts and NFTs. These APIs(subgraphs) are queried with GraphQL.&lt;br&gt;
More in official docs: &lt;a href="https://thegraph.com/docs/en/about/" rel="noopener noreferrer"&gt;https://thegraph.com/docs/en/about/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All humans common language definition:&lt;/strong&gt;&lt;br&gt;
Finding needle in the Blockchain data haystack, this is what Graph let's you to do in quick and easy way.&lt;br&gt;&lt;br&gt;
The Graph is not Google of blockchains. However, unlike Google where users directly type in search queries to find information, The Graph is used by developers. They integrate The Graph into their applications (web3 or Dapp) to query blockchain data efficiently. So, it's like Google's powerful indexing and data retrieval capabilities, but specialised for the world of blockchain data, accessible through a developer's toolkit rather than a simple search bar.&lt;/p&gt;

&lt;p&gt;There are 3 roles in the system: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Indexor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Delegator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Curator&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will use analogy to explain each role in the system, so it's easier to understand. &lt;/p&gt;

&lt;p&gt;Imagine Graph is gigantic library. Library is full of book. Someone needs to maintain those books, keep them in order, suggest new books that should be added to the library, add new books, and keep entire library running smoothly and safely. So lets get started.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Librarian = Indexor
Helper/Investor = Delegator 
Book Scout = Curator
Library user = Graph user
------------------------
Graph    = Library
Subgraph = Book
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine a scenario, you are a research student/library user and you need to find certain information for your thesis. Next day you decide to visit library and see if they have a book that contains data that you need. &lt;/p&gt;

&lt;p&gt;It's Monday, 08:00h in the morning, library just opened, inside the library are &lt;code&gt;librarian&lt;/code&gt; (indexor) and the &lt;code&gt;book scout&lt;/code&gt; (curator). &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Book Scout&lt;/code&gt; (Curator) has been very busy. He has been exploring various sources, looking for Books that contain unique, valuable, or particularly relevant data. When he finds a Book that meets these criteria, he signals its value to the Library with a "recommendation" tag, which effectively is communicated to the Librarians (Indexors). It then is prioritised for acquisition.&lt;br&gt;
This is how &lt;code&gt;books&lt;/code&gt; (Subgraphs) are added to the &lt;code&gt;library&lt;/code&gt; (Graph)&lt;/p&gt;

&lt;p&gt;At roughly 08:30h, you (the &lt;code&gt;student&lt;/code&gt;) are entering the library. Inside the library you are welcomed by the &lt;code&gt;librarian&lt;/code&gt; (indexor), a knowledgeable individual, who manages the organisation and accessibility of the books (subgraphs).&lt;/p&gt;

&lt;p&gt;In a short chat, you explain what kind of topic you are searching, and &lt;code&gt;librarian&lt;/code&gt; (indexor) points you (graph user) to a particularly well-regarded book (subgraph) that covers exactly what they need.&lt;/p&gt;

&lt;p&gt;Now when I have found the book I need, I am ready to borrow it but I only need one piece of information from the book. Good old librarian explains me that there is a new technique where I can take with me a particular piece of the book if I want. That new technique seems like a great idea, he explains that I can specify a "&lt;code&gt;list of data&lt;/code&gt;" (GraphQL query) of certain chapters (fields) and he will service me with exact info that I chose. So this is what I did. I submitted a list to the librarian (sent a query to indexor), who found data in that book (subgraph) and delivered me exactly what I wanted. Wow, super nice!!!  &lt;/p&gt;




&lt;p&gt;It's important to note that Library's vast collection of books and its organised state are partially thanks to &lt;code&gt;Helper/Investor&lt;/code&gt; (Delegator) who, although not actively participating in the day-to-day management, has invested resources into the Library. His support enables the Librarian to maintain and expand the Library's collection, ensuring that it remains a valuable resource for all library users. &lt;br&gt;
In return Helper/Investor (Delegator) is rewarded with a portion of the profit. &lt;/p&gt;

&lt;p&gt;Library user is amazed with how good the library ecosystem is functioning. Helper/Investor helps with his resources (GRT token), book scout (curator) busy as a bee searching and suggesting new great books (subgraphs), while good old librarian (indexor) is always there to serve in best possible way. Therefore in this harmony of collaborative effort they are providing library users (graph users) with access to exact data they need in efficient and accurate way. &lt;/p&gt;

&lt;p&gt;If you have thoughts on how you see the Graph ecosystem, or you would like to add to this analogy, make sure to comment.    &lt;/p&gt;

</description>
      <category>thegraph</category>
      <category>web3</category>
      <category>graphql</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>User should understand blockchain technology?</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Thu, 29 Feb 2024 16:54:57 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/user-should-understand-blockchain-technology-lcl</link>
      <guid>https://dev.to/st1p3kolovrat/user-should-understand-blockchain-technology-lcl</guid>
      <description>&lt;p&gt;Blockchain has been around since 1991. A lot of people relate blockchain to Bitcoin and think Satoshi Nakamoto invented it. What Satoshi did was he combined several existing technologies into one masterpiece, as no one had done before.&lt;/p&gt;

&lt;p&gt;In the 1980s at BellCore, there were two colleagues, Stuart Haber and W. Scott Stornetta, who realized that everything was going to become digital, and digital records can be easily changed. So, the idea of having a need to have immutable records was born. In 1991, they finished their work, but it showed the world and its current technology development was not yet ready for it. So, it waited for many years to get picked up.&lt;/p&gt;

&lt;p&gt;Blockchain technology is more than crypto. Important thing to know is it can be used not only in cryptocurrencies world, but almost everywhere. Why it's not already used in all other aspects of our digital services is another pair of shoes. &lt;/p&gt;

&lt;p&gt;This technology is often thrown out there as buzzword in regular conversations by the business people who may not understand it, but they want to be part of the train that might acquire them some earnings. That is ok, not everyone should be a technologist.&lt;/p&gt;

&lt;p&gt;There are two sides: &lt;code&gt;those who create it and those who use it.&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Those who create it are engineers, and they should know how it works. But should user know how it works?&lt;/p&gt;




&lt;p&gt;Today you are using internet, tv, mobile phone, but do you bother to understand the foundation technology behind the internet, TCP/IP. Do you wonder how your tv converts a digital signal into an image? A tech called DSP. Or have you ever questioned your mobile phone and how the tech behind it enables you to talk and receive messages, GSM/4G/5G, probably no, and you are still an everyday user of all of these three. It's so common and easy to use that you now take it for granted, as if you are entitled to them.&lt;/p&gt;

&lt;p&gt;That should be the goal of engineers: To implement blockchain technology into products that are useful for you, and the only thing that should matter is that the product you are using is useful and easy to use.&lt;/p&gt;

&lt;p&gt;The assumption that understanding the technical details of a technology is essential for its adoption is misleading. Lack of technical knowledge has not stopped the mass adoption of tv/computer/internet/mobile phone. People are generally indifferent to the mechanics of technologies as long as they serve their needs effectively.&lt;/p&gt;

&lt;p&gt;Therefore, leave the details of the problematics to those who are working on finding solutions, everyone else should wait to see if there will be a useful product that they would use.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>qaengineer</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>Docker explained for non-technical people</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Thu, 22 Feb 2024 17:09:22 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/docker-explained-for-non-technical-people-9cb</link>
      <guid>https://dev.to/st1p3kolovrat/docker-explained-for-non-technical-people-9cb</guid>
      <description>&lt;p&gt;Over the years working in software testing I came to realise that there are keywords thrown out there as if everyone understands them. If I know how to use Docker it does not mean everyone else knows it, and to show respect we should always know the audience with who are speaking with and adjust the language so that everyone can understand. Goal is NOT to play smart, but person on the other side to actually understand you. That is also a form of respect. &lt;/p&gt;

&lt;p&gt;Let's imagine a conversation inside a company between QA and Recruiter. Recruiter received a task to hire new QA, and we/company gave him a list of tools a new candidate should have. Recruiter received the info and that's were it usually ends. &lt;br&gt;
Recruiter is left to find a person based on keywords, which is ok, but what if I, you or your colleague actually take a bit of time and help your recruiter to better understand what certain tool does for us. &lt;br&gt;
Now, you can say: "OK, let recruiter google it, I don't have time". Fine, thats what everyone has been doing since Google is founded. &lt;/p&gt;

&lt;p&gt;Remember this old wisdom: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give a man a fish, and you feed him for a day. Teach a man to fish, and you feed him for a lifetime.&lt;/p&gt;
&lt;/blockquote&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%2Fkd2cnw6psgpc4y451ciz.jpg" 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%2Fkd2cnw6psgpc4y451ciz.jpg" alt=" " width="799" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To show some respect, take a bit of your time and explain in real life examples a certain tool so that anyone who heard about that tool can understand what it does. High level is enough. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the goal? Why would you waste your time?&lt;/strong&gt; &lt;br&gt;
Sharing knowledge is never wasted time. It's called help. Helping someone to understand, will help him to do his job better, and ultimately find a better colleague who will work with you everyday.&lt;br&gt;&lt;br&gt;
Sharing knowledge is something you should be excited about. It should give you a feeling of satisfaction/accomplishment.  &lt;/p&gt;




&lt;p&gt;Let's write this in a dialog between me and recruiter. &lt;br&gt;
Imagine a video call between two colleagues in the company. Recruiter Marco and QA Stipe :-)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiter:&lt;/strong&gt; &lt;code&gt;Ok, amigo. Tell me what is Docker&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Stipe:&lt;/strong&gt; Docker is a platform. There are buzz words such as container and image. But don't worry too much about them. &lt;br&gt;
Imagine a container as your own virtual machine where you can install OS (such as Ubuntu, Windows, ...), libraries, programming languages, applications, etc. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiter:&lt;/strong&gt; &lt;code&gt;OK, and?&lt;/code&gt; &lt;br&gt;
&lt;strong&gt;Stipe:&lt;/strong&gt; And now you can use that container and run your application on it, or you can run automated tests. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiter:&lt;/strong&gt; &lt;code&gt;Hmm, interesting. Can you tell me more but use some kind of real-life analogy&lt;/code&gt; &lt;br&gt;
&lt;strong&gt;Stipe:&lt;/strong&gt; Sure, imagine there is a chef who works in portable kitchen on various venues and events to cook meals. &lt;br&gt;
Before event each portable kitchen is equipped with all the chef's tools, ingredients, and recipes. No matter the location of the event chef always has same conditions for cooking his meals. So he can cook meal in the same way each time, without any external factors as disturbance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiter:&lt;/strong&gt; &lt;code&gt;Mmmm, I'm listening&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Stipe:&lt;/strong&gt; You can look at portable kitchen as Docker container, while ingredients/tools/recipe inside his portable kitchen are libraries/tools/os. You see where I am getting? &lt;br&gt;
This means Docker delivers to your entire team one environment for working. Their local computer, different versions of this and that are irrelevant, they can now bring that container up spin their application in it, deploy, run, test. And with that, a legendary headache of "it works on my machine" is resolved, because everyone has same versions of everything.       &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recruiter:&lt;/strong&gt; &lt;code&gt;Oh, now I get it. Docker is brilliant&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Stipe:&lt;/strong&gt; It sure is. I'm glad you understand it better now :-)&lt;/p&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>hiring</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Selenium/Playwright explained to non-technical person</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Sun, 18 Feb 2024 22:52:34 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/seleniumplaywright-explained-to-non-technical-person-3b7o</link>
      <guid>https://dev.to/st1p3kolovrat/seleniumplaywright-explained-to-non-technical-person-3b7o</guid>
      <description>&lt;p&gt;Aimed to non-technical audience, this post explains what is automation tool &lt;strong&gt;selenium&lt;/strong&gt; and &lt;strong&gt;playwright&lt;/strong&gt;, in everyday analogy. &lt;/p&gt;

&lt;p&gt;Imagine Selenium or Playwright as professional bodyguard assigned to protect bustling metropolis called "&lt;a href="https://de.linkedin.com/company/about-you" rel="noopener noreferrer"&gt;About YOU&lt;/a&gt; webshop" &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%2Fk36csazxih22hz49nlxe.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%2Fk36csazxih22hz49nlxe.png" alt=" " width="329" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This web metropolis is filled with various items, offering various clothing, shoes, accessories, etc. And quite often it has discounts, and best deals. This marketplace is constantly evolving, and the traffic is insane. To keep lifeline of the system running a good old bodyguard Selenium-Playwright is on his constant watch.   &lt;/p&gt;

&lt;p&gt;This digital metropolis consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;citizens (aboutyou users)&lt;/li&gt;
&lt;li&gt;storefronts (webshop pages)&lt;/li&gt;
&lt;li&gt;store item barcode (element locator)&lt;/li&gt;
&lt;li&gt;and much more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mission of Mr. Selenium-Playwright is to make sure daily flow, and functionality of the metropolis is working seamlessly.&lt;br&gt;&lt;br&gt;
Just as bodyguard protects and prevents certain problems, Mr. Selenium-Playwright mimicks user interaction to ensure every part of the metropolis works as expected. He can blend in using different disguises(browser) to ensure his employer understands the experience of every citizen(user). &lt;/p&gt;




&lt;h3&gt;
  
  
  Wanna find out how does a normal day look like for bodyguard Mr. Selenium-Playwright?
&lt;/h3&gt;

&lt;p&gt;Ok let's dive into it.&lt;/p&gt;

&lt;h6&gt;
  
  
  1. Patrolling metropolis
&lt;/h6&gt;

&lt;p&gt;Every day, mimicking citizen behaviour he goes through every storefront, including store items all through the cash register, where he confirms he can purchase items without any issues. He executes all actions citizens would normally do.  &lt;/p&gt;

&lt;p&gt;Therefore, he regularly walks through the digital streets(executing automated tests) and ensures all storefronts(webshop pages) are working and makes sure citizens(users) can use them without experiencing any faulty(bugs) behaviour that may cause metropolis to close down or repel user from entering once again.   &lt;/p&gt;

&lt;h6&gt;
  
  
  2. Catching and identifying
&lt;/h6&gt;

&lt;p&gt;Each time he executes a list of scenarios citizen(user) would do, there is a result at the end of each scenario. Sometimes those scenarios result in finding bugs/issues. He gathers evidence, and gives exact location of faulty(bug) behaviour, and a screenshot.  &lt;/p&gt;

&lt;h6&gt;
  
  
  3. Reporting
&lt;/h6&gt;

&lt;p&gt;At the end of each run of citizen behaviour test, he gives a nice report. This report is delivered to his boss. In that report he displays how many scenarios he executed, how many of them passed and how many are with faulty behaviour.   &lt;/p&gt;

&lt;h3&gt;
  
  
  For what is Mr. Selenium-Playwright useful?
&lt;/h3&gt;

&lt;p&gt;In the narrative of "AboutYou Webshop" Selenium and Playwright automation tools stand as the guardian of the digital city, working tirelessly behind the scenes to ensure that every user action, application functionality, elements is as smooth as a well-oiled machine. Magic of how Selenium or Playwright can execute all of these tests lays in hands of your software tester aka QA Engineer. That individual will write code for each scenario and add that to a continuous integration job, where those tests will be run on a certain schedule&lt;/p&gt;




&lt;h6&gt;
  
  
  Facts about automated tests:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;they run faster then any other manual testing&lt;/li&gt;
&lt;li&gt;reports are delivered after each test run&lt;/li&gt;
&lt;li&gt;repetitive regression testing is no longer boring &lt;/li&gt;
&lt;li&gt;find out if new features blend in with existing ones perfectly or they break something&lt;/li&gt;
&lt;li&gt;saves time which gives QA Engineer more time to focus on complex testing scenarios that may require human judgment&lt;/li&gt;
&lt;li&gt;win on the long run (the more automated tests you have the bigger ROI)&lt;/li&gt;
&lt;li&gt;more time for exploratory testing&lt;/li&gt;
&lt;li&gt;more time for writing new automated tests&lt;/li&gt;
&lt;li&gt;covers more combinations than any human can in given time&lt;/li&gt;
&lt;li&gt;eliminates human error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How you find this article? Let me know in the comments.&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>playwright</category>
      <category>softwaretesting</category>
      <category>hiring</category>
    </item>
    <item>
      <title>Can IT company survive without QA?</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Mon, 12 Feb 2024 11:42:55 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/can-it-company-survive-without-qa-e22</link>
      <guid>https://dev.to/st1p3kolovrat/can-it-company-survive-without-qa-e22</guid>
      <description>&lt;p&gt;In always fast-developing technological world, the question whether an IT company can survive without having a Quality Assurance (QA) team or not seems to be actual as never before.&lt;/p&gt;

&lt;p&gt;Being small private IT company or big, pace is always the same, speed in delivery is important. Competition is big, customers are nowadays having less patience. Every detail matters, from UX to quality of the product. If you want to succeed, having smooth user experience is the key. When you signup to the service, if experience at first minute is not good, your potential customer is gone to the competitor. Same goes for every feature you have inside. Everything matters. Some more than other, but ultimately quality is the key. &lt;/p&gt;

&lt;p&gt;If you are super small company, a startup, you might want to cut expenses and live on the edge for a while. That is understandable. In such case when you get on your feet, and you decide that flying in a non-tested brand new airplane is still good idea, it is your legitimate right. That airplane can have malfunction and crash any second now, however with lots of good luck it may be success. Question is, do you want to invest your time/money into a company that is basing its success on luck?   &lt;/p&gt;




&lt;p&gt;In software delivery cycle, quality assurance is very important process to quality development, it is ensuring that product attains certain levels of quality before it lands in the hands of the user. One thing we all need to accept, is that we are humans and we all make mistakes. That is normal. Some make more, some make less. Without QA, companies release their products with bugs, security gaps, and risk having their reputation and financial base collapsed.&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%2Fuzc57xzgwzz5n2atu4em.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%2Fuzc57xzgwzz5n2atu4em.png" alt=" " width="479" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;QA is not only about finding bugs but more about proving the product is reliable, user-friendly, and meeting the expectations of its users. Those are the goals. If the company wants to attain high level of quality, entire company needs to be more educated in quality assurance. Mindset is the key. Being safe is always better then being fastest. &lt;/p&gt;

&lt;p&gt;Would you rather buy nicest looking fast car with highest speed and newest tech &lt;strong&gt;but you know it is not tested for safety&lt;/strong&gt;, or would you drive competitors car who released slightly later but it passed all the safety and quality tests? &lt;br&gt;
I presume decision would be on the latter&lt;/p&gt;

&lt;p&gt;If you run a IT company, and you don't have a QA, you should consider adding testing into your delivery process.&lt;br&gt;&lt;br&gt;
There are different types of testing, and depending on what QA resources you have, QA team covers an all-round check of the product as far as its functionality, happy-path covering, negative-path covering, edge-case covering, usability, frontend manual and automated testing, api manual and &lt;br&gt;
automated testing, etc. &lt;/p&gt;

&lt;p&gt;All of this will depend on the developers to find and fix all the problems without any QA. That will only slow down the development pace and remove resources from innovative work.&lt;br&gt;
Also mindset of a developer and QA is very different oriented. &lt;br&gt;
In my experience, QA can find 10 bug where dev can not see 1 bug looking at his code.   &lt;/p&gt;

&lt;p&gt;In conclusion, theoretically, an IT company might manage without the QA team, but practically, without it, the quality of products would be more likely compromised, and satisfaction of the customers on the long run, its in great danger. There is no overstating the importance of quality assurance in the software development life cycle because it is an indispensable part of the cycle.&lt;/p&gt;

</description>
      <category>opentowork</category>
      <category>softwaredevelopment</category>
      <category>qualityassurance</category>
      <category>startup</category>
    </item>
    <item>
      <title>Idempotency explained in restaurant analogy</title>
      <dc:creator>Stipe</dc:creator>
      <pubDate>Sat, 03 Feb 2024 21:32:21 +0000</pubDate>
      <link>https://dev.to/st1p3kolovrat/idempotency-explained-in-restaurant-analogy-4ok</link>
      <guid>https://dev.to/st1p3kolovrat/idempotency-explained-in-restaurant-analogy-4ok</guid>
      <description>&lt;p&gt;In a bustling city of New York, there was a renowned restaurant named "Giovanni". This restaurant was unique for it's traditional meals from south of Italy, and they served meals in the same concept of idempotency in API development. &lt;/p&gt;

&lt;p&gt;In the sphere of APIs, idempotency means that regardless of how many times one makes identical request, the outcome remains unchanged after the first request is made. This principle is ingeniously applied in the old Giovanni's restaurant. &lt;/p&gt;

&lt;p&gt;Enter our protagonist, a chef named Marco, culinary virtuoso. Marco's kitchen was the heart of idempotency magic. Each dish was like a unique response to the API request made by the customer. Made with love, taste and never duplicated. &lt;/p&gt;

&lt;p&gt;One summer evening, a couple on their first date arrived at "Giovanni" restaurant. Arthur and Brenda. &lt;/p&gt;

&lt;p&gt;Arthur ordered a nice stake, while Brenda ordered a dish called "Palermo delight". Order went to kitchen with unique identifier "&lt;strong&gt;table #6 - order 130&lt;/strong&gt;". Arthur was a rascal and always ready for some misdeeds. He called waiter and ordered same meals again, hoping to see if they would end up with two dishes instead of one. &lt;/p&gt;

&lt;p&gt;Back in the kitchen chef Marco received again identical order with same unique identifier "&lt;strong&gt;table #6 - order 130&lt;/strong&gt;". &lt;/p&gt;

&lt;p&gt;Marco immediately recognized the duplicate. He informed entire team in the kitchen that this is idempotent request and they should prepare only one stake and one Palermo delight. In any other restaurant this would resulted with duplicate order, but not in Giovanni's. &lt;/p&gt;

&lt;p&gt;Rascal Arthur and Brenda were served with one order, corresponding to their first order.&lt;/p&gt;

&lt;p&gt;Let's break down the process from order to serving of the meal. &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;1. MEAL ORDER = POST REQUEST&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Arthur and Brenda's first order of stake and Palermo delight equals to a POST request to an API. &lt;br&gt;
When POST request is made, it sends data to the server, ordering to cook meals. &lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. ORDER NUMBER = UNIQUE IDENTIFIER&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once Arthur and Brenda told what they want to eat, waiter assigned a table number and order number to it. Order was taken to the kitchen. This unique identifier is crucial.&lt;br&gt;
It ensures that even if same order is placed 20 times, it will be recognized as duplicate.&lt;/p&gt;

&lt;p&gt;This means, when api request is made, we assign it a unique identifier, ensuring server recognizes it and prevents duplications, server overload and poor user experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. KITCHEN PROCESSING ORDER = SERVER PROCESSING THE REQUEST&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Kitchen took the order with unique identifier, and places it into schedule of cooking. Arthur thought he is clever, but chef Marco's idempotent system is without flaw. &lt;/p&gt;

&lt;p&gt;You can look at this as user making same api request again and again, perhaps due to network issue or serial clicking mania :-) &lt;br&gt;
All of these requests will be recognized to who they belong, they will then be ignored, and only first request will be executed. &lt;/p&gt;




&lt;p&gt;User is unaware of checks that occur behind the scenes, and he is served with what he requested in the first place. And that is most important. &lt;/p&gt;

&lt;p&gt;How do you look at idempotency? Share your view. &lt;/p&gt;

</description>
      <category>idempotency</category>
      <category>programming</category>
      <category>api</category>
      <category>softwaretesting</category>
    </item>
  </channel>
</rss>
