<?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>Forem: Jonas Menesklou</title>
    <description>The latest articles on Forem by Jonas Menesklou (@lumpin).</description>
    <link>https://forem.com/lumpin</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%2F860514%2F42c9d746-b060-4c52-9a8a-343af5db1376.png</url>
      <title>Forem: Jonas Menesklou</title>
      <link>https://forem.com/lumpin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lumpin"/>
    <language>en</language>
    <item>
      <title>AskUI Best Practices</title>
      <dc:creator>Jonas Menesklou</dc:creator>
      <pubDate>Thu, 15 Sep 2022 10:52:23 +0000</pubDate>
      <link>https://forem.com/askui/askui-best-practices-eo8</link>
      <guid>https://forem.com/askui/askui-best-practices-eo8</guid>
      <description>&lt;p&gt;Let’s be honest: Testing is a lot of fun. Not only is it extremely important for the success of your team, but it is also highly satisfying when you’ve finally found and tracked a pesky bug all the way to its original source.&lt;/p&gt;

&lt;p&gt;However, setting up your first test case in a new environment can be tiresome, especially when every testable element has to be &lt;strong&gt;individually defined&lt;/strong&gt; first. Before you know it, you are knee-deep in someone else's messy code, trying to put IDs in the right places so that you can run a simple workflow, that would take a manual tester five seconds to complete. This approach seems a little impractical, doesn’t it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Way: Selector-Free Test Automation
&lt;/h2&gt;

&lt;p&gt;If you feel like current testing tools are holding back your productivity - don’t worry, you are not alone. At askui, we firmly challenge the idea of selector-based testing. We believe that humans are still the best testers, because of two simple reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They are quick&lt;/li&gt;
&lt;li&gt;They are resistant to changes in the codebase (lol, obviously)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to automate this boring, repetitive work, future testing methods will need to be even better than humans. That’s why our mission is to &lt;strong&gt;provide human-level test quality at scale and at a fraction of the cost&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;askui uses artificial intelligence to detect on-screen elements such as buttons and text fields automatically, allowing you to skip the usual lengthy setup process, so that you can start writing test cases right away. &lt;/p&gt;

&lt;h2&gt;
  
  
  How Does This Work?
&lt;/h2&gt;

&lt;p&gt;The cool thing about askui is that you can approach writing test automation scripts as if you would manually perform the actions yourself. As a result, you get a more intuitive workflow that can save you a lot of time. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before you continue:&lt;/strong&gt; If you haven’t yet downloaded askui, &lt;a href="https://bit.ly/3AAwmJ1" rel="noopener noreferrer"&gt;follow this guide on installing the app on your machine&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up a Test Suite
&lt;/h3&gt;

&lt;p&gt;💭 Let’s say we’re on &lt;a href="http://google.com" rel="noopener noreferrer"&gt;google.com&lt;/a&gt; and we want to &lt;strong&gt;search for an image of a cat and then download it to our computer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, we break this task down into steps that a user would take. Then we can recreate those steps in code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;go to google images&lt;/li&gt;
&lt;li&gt;type “cat” in the search bar&lt;/li&gt;
&lt;li&gt;select image&lt;/li&gt;
&lt;li&gt;right-click + save the image&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then we begin creating our test suite, by creating two separate test blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first one is used to get an annotated screenshot, where all of the on-screen elements are enclosed within &lt;strong&gt;annotated bounding boxes&lt;/strong&gt;. This will help us select the correct elements in our test case.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;annotate&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="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;aui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&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;/li&gt;
&lt;li&gt;
&lt;p&gt;the second test block contains our actual test case.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;xit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should click download cat image&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="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;aui&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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’ll notice, that the it function is “x’ed out”, which means, that the test block will be ignored, when we run the script. This is fine for now, because it does not contain anything yet. &lt;/p&gt;

&lt;p&gt;Next, you’ll run the script to create an annotated screenshot. If you’re using VS Code, it will appear in your file navigation bar on the left.&lt;/p&gt;

&lt;p&gt;📋 The annotations are basically the substitute for IDs in selector-based testing. &lt;br&gt;
You can can click on them to copy them into your clipboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing and Debugging a Test Case
&lt;/h3&gt;

&lt;p&gt;Now we can start to write our test case, by locating the elements and then executing an action on them. Remember the steps, that we wanted to recreate?&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt; go to google images&lt;/li&gt;
&lt;li&gt; type “cat” in the search bar&lt;/li&gt;
&lt;li&gt; select image&lt;/li&gt;
&lt;li&gt; right-click + save the image&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the end, your test case could look something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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;aui&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;./helper/jest.setup&lt;/span&gt;&lt;span class="dl"&gt;'&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;jest with askui&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should click on text&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="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;aui&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Images&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="nf"&gt;rightOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gmail&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="nf"&gt;exec&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;aui&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;typeIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&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="nf"&gt;textfield&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;below&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logo&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;G00g.e&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="nf"&gt;exec&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;aui&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pressKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;enter&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="nf"&gt;exec&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;aui&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveMouseTo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;above&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pet guru Yuki Hattori explaiinICats&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="nf"&gt;exec&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;aui&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mouseRightClick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec&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;aui&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;save image as&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="nf"&gt;exec&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;aui&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Save&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="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;xit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;annotate&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="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;aui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Debugging
&lt;/h3&gt;

&lt;p&gt;It’s possible that you’ll run into problems with locating functions. For example, when creating this tutorial, we first tried to locate the image nearest to the image title, like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;aui&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveMouseTo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nearestTo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pet guru Yuki Hattori explaiinICats&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="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it turns out, that the AI uses a different metric for measuring distance between elements, which is why our script failed the first time. Then we substituted this function for above(), which fixed the problem for us.&lt;/p&gt;

&lt;p&gt;If you have a similar issue, try to play around with the functions and see if you can tackle the problem from a different angle.&lt;/p&gt;

&lt;p&gt;if you have a recurring or persisting issue, don’t hesitate to &lt;a href="https://bit.ly/3ekHnGR" rel="noopener noreferrer"&gt;ask the community&lt;/a&gt; for help. You can be sure that your questions will be answered there. We’re excited to hear about how you apply askui on your projects.&lt;/p&gt;

&lt;p&gt;If you have any feature requests, please feel free to &lt;a href="https://bit.ly/3AP20T7" rel="noopener noreferrer"&gt;post them in our featurebase board&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Best regards and happy testing!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>UI Automation for Flutter Apps</title>
      <dc:creator>Jonas Menesklou</dc:creator>
      <pubDate>Mon, 01 Aug 2022 18:26:00 +0000</pubDate>
      <link>https://forem.com/askui/ui-automation-for-flutter-apps-5a9i</link>
      <guid>https://forem.com/askui/ui-automation-for-flutter-apps-5a9i</guid>
      <description>&lt;p&gt;In today's tutorial we will show how to automate Flutter applications with askui. Please also find a video tutorial &lt;a href="https://www.youtube.com/watch?v=KLz18ckWwuo" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We assume that askui is already installed in a clean state, see &lt;a href="https://dev.to/askui/getting-started-with-askui-1idl"&gt;here&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Flutter is an open-source UI development kit from Google available since 2017. The special feature of Flutter is the possibility of cross-platform development of applications for Android, iOS, Linux, macOS, Windows, Google Fuchsia and web.&lt;/p&gt;

&lt;p&gt;Due to this advantage, it quickly became known as a popular framework and various companies are already using it.&lt;/p&gt;

&lt;p&gt;If you follow the interest over time, it quickly becomes clear that Flutter will probably be one of the most popular frameworks in the future.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fy2njlwkdlm9gimx0bcpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fy2njlwkdlm9gimx0bcpv.png" alt="Interest over time in Flutter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the Flutter App
&lt;/h2&gt;

&lt;p&gt;Since this tutorial is about automating flutter apps and not about development, we use the &lt;a href="https://app.flutterflow.io/run/1E6pv4HAPn7zBGaHYtMx" rel="noopener noreferrer"&gt;Health.ai&lt;/a&gt; Flutter Demo App as from &lt;a href="https://flutterflow.io/" rel="noopener noreferrer"&gt;Flutterflow.io&lt;/a&gt; as an example. The startup from Silicon Valley offers a low-code builder for creating Flutter Apps.&lt;/p&gt;

&lt;p&gt;In principle, however, it does not matter how the Flutter app is developed and hosted. Since askui only accesses the operating system and not the application itself, we can implement a true black box test. &lt;br&gt;
If you want to test a mobile application, you start it on an emulator on the test system. As soon as the emulator is visually visible, it can be controlled with askui.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Using the adb shell, the askui runner can also be installed on Android and thus run on a real device. More about this in a later tutorial.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Health.ai app under test looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvqu3nhs0f0ukut26xv76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvqu3nhs0f0ukut26xv76.png" alt="The Health.ai app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a simple test, we would like to test the login process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating with askui
&lt;/h2&gt;

&lt;p&gt;The login process basically consists of the following three steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entering the username, in our case an account has already been created at "&lt;a href="mailto:info@askui.com"&gt;info@askui.com&lt;/a&gt;",&lt;/li&gt;
&lt;li&gt;Entering the password, in this case "test123",&lt;/li&gt;
&lt;li&gt;Click on the login button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Besides that, it matters how and the app is hosted. In our case in a web browser, so an open browser is the precondition for running the test. We can start the app using the following code in the &lt;em&gt;my-first-askui-test-suite.test.ts&lt;/em&gt; file:&lt;/p&gt;

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

await aui.typeIn("https://app.flutterflow.io/run/1E6pv4HAPn7zBGaHYtMx").url().exec();
await aui.pressKey('enter').exec();


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

&lt;/div&gt;

&lt;p&gt;After running, the browser should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxoc0paa2gssu4we4waiw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxoc0paa2gssu4we4waiw.png" alt="Browser after starting the app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If a mobile emulator is used, the app must be launched in it beforehand and the emulator must be visually visible on the screen.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next we want to automate the filling of the text fields. To better understand how these elements are recognized, we add a help test case, which saves the screenshots with the recognized elements in a separate folder, we add the following lines:&lt;/p&gt;

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

  it('Annotation', async () =&amp;gt; {
    await aui.annotate();
  });


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

&lt;/div&gt;

&lt;p&gt;With each new test run, a new html document is now stored in the &lt;em&gt;report&lt;/em&gt; folder. If we copy the relative path of this file into our browser, we can check what the askui AI has recognized.&lt;/p&gt;

&lt;p&gt;Now, to fill in the actual text fields, we use the following code after starting the application:&lt;/p&gt;

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

await aui.typeIn("info@askui.com").textfield().contains().withText("Email Address").exec();
await aui.typeIn("test123").textfield().contains().withText("Password").exec();


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

&lt;/div&gt;

&lt;p&gt;The following command is used to perform the login:&lt;/p&gt;

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

await aui.click().text().withText("Login").exec();


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

&lt;/div&gt;

&lt;p&gt;The subsequent verification of the successful login is checked by the appearance of the &lt;em&gt;Good Morning&lt;/em&gt; text, which appears after the successful login:&lt;/p&gt;

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

await aui.expect().text().withText("Good Morning").exists();


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Adding all up
&lt;/h2&gt;

&lt;p&gt;The complete test file should now look like this:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { aui } from './helper/jest.setup';

describe('jest with askui', () =&amp;gt; {
  it('Flutter App Login Form', async () =&amp;gt; {

//Open Flutter App
await aui.typeIn("https://app.flutterflow.io/run/1E6pv4HAPn7zBGaHYtMx").url().exec();
await aui.pressKey('enter').exec();

//Fill In Form
await aui.typeIn("info@askui.com").textfield().contains().withText("Email Address").exec();
await aui.typeIn("test123").textfield().contains().withText("Password").exec();

//Login
await aui.click().text().withText("Login").exec();

//Verify Login
await aui.expect().text().withText("Good Morning").exists();

  });

  it('Annotation', async () =&amp;gt; {
    await aui.annotate();
  });

});


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

&lt;/div&gt;

&lt;p&gt;You can now run the whole file with the command &lt;code&gt;npx jest --config ./test/jest.config.ts;&lt;/code&gt;. Just make sure the app is visible on the test system (in this case your screen).&lt;/p&gt;

&lt;p&gt;You can also find the complete project &lt;a href="https://github.com/Lumpin-askui/Flutter-Automation" rel="noopener noreferrer"&gt;here&lt;/a&gt; on Github.&lt;/p&gt;

&lt;p&gt;Happy testing!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>flutter</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started With askui</title>
      <dc:creator>Jonas Menesklou</dc:creator>
      <pubDate>Thu, 09 Jun 2022 16:06:10 +0000</pubDate>
      <link>https://forem.com/askui/getting-started-with-askui-1idl</link>
      <guid>https://forem.com/askui/getting-started-with-askui-1idl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Tip: Watch our how to get started video &lt;a href="https://www.youtube.com/watch?v=95HFXgqXPtI" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Test automation is still considered a bottleneck in modern software development. Especially UI automation can be quite challenging in certain cases. Despite countless frameworks and tools, it is very difficult to automate applications across operating systems, although cross-platform workflows play an increasingly important role. For example, testing a 2-factor authentication of a web application via smartphone is almost impossible to automate as an end-to-end process.&lt;/p&gt;

&lt;p&gt;askui tries to close this gap by rethinking UI automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  About askui
&lt;/h2&gt;

&lt;p&gt;Basically, askui is a platform-independent, selector-free UI automation framework. Instead of controlling elements via selectors such as &lt;em&gt;XPath&lt;/em&gt; or &lt;em&gt;CSS&lt;/em&gt; selectors and thus being limited to web applications, askui controls the UI at the operating system level.&lt;/p&gt;

&lt;p&gt;For making this possible, a neural network was trained on the appearance of UI elements in order to localize UI elements based on screenshots. These are then matched with an instruction that is unique for the respective element. The final execution of the instruction happens via mouse and keyboard control on the operating system. Such an instruction could be for example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aui.click().button().below().text().withText("Password").exec();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we take a look at the corresponding UI, it quickly becomes clear which action is to be executed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jhpm80ee9urmzzwocq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jhpm80ee9urmzzwocq8.png" alt="Image description" width="346" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The instruction describes a click on a button below a certain text, in this case &lt;em&gt;Password&lt;/em&gt;. Visually, there is only one button here, so when the action is executed, a click on the blue &lt;em&gt;Login&lt;/em&gt; button is performed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why askui
&lt;/h2&gt;

&lt;p&gt;In principle, one can of course ask whether another test automation tool is needed after Selenium and co. If you look at the development of the last few years, you will notice that websites and apps are using more and more new technologies, e.g. &lt;a href="https://www.w3schools.com/tags/tag_iframe.asp" rel="noopener noreferrer"&gt;iFrame&lt;/a&gt; or &lt;a href="https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/" rel="noopener noreferrer"&gt;ShadowDOM&lt;/a&gt;, and third-party systems, which make it more difficult to automate them. Instead of developing a separate automation solution for each new technology, askui wants to act independently of these developments and act as a future-proof framework for UI automation of any operating system. The following advantages result from the approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test instructions are written in &lt;em&gt;UI language&lt;/em&gt; and are thus easy to understand.&lt;/li&gt;
&lt;li&gt;No access to code selectors is needed. Thus the tests are independent of changes in the program code and run very stable.&lt;/li&gt;
&lt;li&gt;Elements are found visually by an AI and not by pixel-matching. This makes the automation completely independent of the resolution and design of the UI elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the following, we will take a look at the first steps in askui.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the IDE
&lt;/h2&gt;

&lt;p&gt;askui is an &lt;a href="https://github.com/askui/askui" rel="noopener noreferrer"&gt;open source framework &lt;/a&gt; with a public &lt;a href="https://docs.askui.com/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. You can install askui in an IDE of your choice, we will use Visual Studio Code in the following. Firstly, open the folder where we want to install askui. In my example this folder is called "Installation". It should look something like this:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uf3fw1vh7h2sm024dyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uf3fw1vh7h2sm024dyj.png" alt="Image description" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we need to set up the npm project. For this we open the terminal and type the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a &lt;em&gt;package.json&lt;/em&gt; file with descriptions and dependencies of the project. The next step is the installation of askui itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing askui
&lt;/h2&gt;

&lt;p&gt;The following command is used for installing askui:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D askui&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Thereby askui library provides everything needed for the automation of the operating system. It does not yet provide everything you need for writing and executing a test. You also need a way of&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;writing up the actual test,&lt;/li&gt;
&lt;li&gt;writing up assertions to test wehther an expectation holds true and, last but not least,&lt;/li&gt;
&lt;li&gt;a way to execute the tests, i.e., a test runner.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One framework which provides all of this out of the box is &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; which we are going to use in this example as it is quite easy to get started with and well-known. But feel free to use another test framework, such as &lt;a href="https://jasmine.github.io/" rel="noopener noreferrer"&gt;Jasmine&lt;/a&gt; or &lt;a href="https://mochajs.org/" rel="noopener noreferrer"&gt;Mocha&lt;/a&gt;. How you use the askui library should be pretty much the same across these frameworks. For installing Jest, type the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D jest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Furthermore, we are going to use &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; for writing the test instead of plain JavaScript. Run the following command to install Typescript, TS-Node for using Typescript together with Node.js and the types of Jest and Node.js.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i -D @types/jest ts-jest ts-node typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Your IDE then should look similar to this:&lt;/p&gt;

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

&lt;p&gt;Now, we are ready to write our first test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Your First Test
&lt;/h2&gt;

&lt;p&gt;For creating your first test suite, type following in the terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx askui init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a few files, read &lt;a href="https://docs.askui.com/docs/general/Getting%20Started/writing-your-first-test" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you want to learn more about them. &lt;/p&gt;

&lt;p&gt;We will just focus on &lt;em&gt;test/my-first-askui-test-suite.test.ts&lt;/em&gt; for now. This file includes your first example test which should look like this:&lt;/p&gt;

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

&lt;p&gt;This test is going to click on a random text on your screen after executing. But before we execute it, we want to make sure it will execute on the right screen. Therefore, we will check the file &lt;em&gt;test/helper/jest.setup.ts&lt;/em&gt;. There you will find a setting for &lt;em&gt;display&lt;/em&gt; which is by default set to &lt;em&gt;0&lt;/em&gt;. This means the test will be executed on your main display. If you don't have any external screen this setting can be ignored. If you do have external screens, you should set it to the screen you want to automate on, e.g. for the first external monitor, change it to &lt;em&gt;1&lt;/em&gt; and so on.&lt;/p&gt;

&lt;p&gt;Now we are ready to execute our first test. Therefore, we type following command in the terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx jest test/my-first-askui-test-suite.test.ts --config ./test/jest.config.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should now see the test suite being executed inside the shell and, actually, your cursor should move to some text shown on your screen and click on that text. 🎉 Congratulations! You just executed your first test suite using askui.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: If you want to see what the AI model detects on your screen, use the &lt;em&gt;annotateInteractively&lt;/em&gt; (see &lt;a href="https://docs.askui.com/docs/general/Tooling/annotate-interactively" rel="noopener noreferrer"&gt;here&lt;/a&gt;) command. It will create an overlay where you can check all detected UI elements and their classification.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>tutorial</category>
      <category>testing</category>
      <category>opensource</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
