<?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: okarsono</title>
    <description>The latest articles on Forem by okarsono (@okarsono).</description>
    <link>https://forem.com/okarsono</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%2F1093648%2Fccfcbb77-9467-4789-9e3a-3d8fe8b6965e.jpeg</url>
      <title>Forem: okarsono</title>
      <link>https://forem.com/okarsono</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/okarsono"/>
    <language>en</language>
    <item>
      <title>Capturing browser console logs on automated test</title>
      <dc:creator>okarsono</dc:creator>
      <pubDate>Thu, 01 Jun 2023 13:43:02 +0000</pubDate>
      <link>https://forem.com/okarsono/capturing-browser-console-logs-on-automated-test-3p1e</link>
      <guid>https://forem.com/okarsono/capturing-browser-console-logs-on-automated-test-3p1e</guid>
      <description>&lt;p&gt;Test flakiness is not only annoying, but also costing time, energy, and money in the long run. That's why it is important to deal with them as soon as possible.&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%2Fcnlofymuvsslz63xy38b.jpg" 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%2Fcnlofymuvsslz63xy38b.jpg" alt="Flaky test meme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the most challenging test type to debug and fix when flakiness occurs is feature test with browser testing. This is because there are usually many elements involved in the test (backend/server, the test spec, and the browser controller) and these elements have to work together in the correct manner for the test to run. Most of the time, flakiness occurs due to race condition (the browser controller was too fast for the backend, etc)&lt;/p&gt;

&lt;p&gt;Recently our application, which is built on Ruby on Rails on the backend suffers from test flakiness during CI. Our feature tests are setup to use Capybara with Selenium Chrome driver, and when the test failed, it failed at random points with error message that's too generic. Making things complicated is the fact that tests that succeed locally failed on Travis CI.&lt;/p&gt;

&lt;p&gt;Unable to simulate the failing tests, I had to resort to different method: &lt;strong&gt;figure out what the browser console output at the time of failure&lt;/strong&gt;. With only headless mode available on Travis CI, this can be done programatically:&lt;/p&gt;

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

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;console_logs&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Please note that the &lt;code&gt;selenium-webdrivers&lt;/code&gt; gem need to be the newer version (v4 onwards) for this to work.&lt;/p&gt;

&lt;p&gt;By default this will only capture log messages on warn/fatal level (output from &lt;code&gt;console.warn&lt;/code&gt; and &lt;code&gt;console.error&lt;/code&gt;). To retrieve the log messages on info/debug level, I needed to change Selenium Chrome's logging preference option:&lt;/p&gt;

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

&lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_driver&lt;/span&gt; &lt;span class="ss"&gt;:chrome&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;chrome_options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Selenium&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WebDriver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Chrome&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

  &lt;span class="n"&gt;chrome_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logging_prefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;browser: &lt;/span&gt;&lt;span class="s1"&gt;'ALL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Capture JavaScript errors&lt;/span&gt;
    &lt;span class="ss"&gt;driver: &lt;/span&gt;&lt;span class="s1"&gt;'SEVERE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# Capture WebDriver errors&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;http_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Selenium&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;WebDriver&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Remote&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Http&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

  &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;browser: :chrome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;options: &lt;/span&gt;&lt;span class="n"&gt;chrome_options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;http_client: &lt;/span&gt;&lt;span class="n"&gt;http_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Selenium&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;options&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 it folks. Hope that helps somebody too.&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>frontend</category>
      <category>testing</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
