
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Browser-Extensions | karas.codes</title>
        <link>https://karas.codes/tags/browser-extensions/</link>
        <description>Articles tagged Browser-Extensions on karas.codes</description>
        
        <language>en-us</language>
        <copyright>© Andrzej Karaś</copyright>
        <lastBuildDate>Fri, 17 Mar 2023 00:00:00 +0000</lastBuildDate>
        
        <atom:link href="https://karas.codes/tags/browser-extensions/index.xml" rel="self" type="application/rss+xml" />
        
        
        
        <item>
            <title>How Making Coffee Helped Me Find a Bug</title>
            <link>https://karas.codes/posts/how-did-making-making-coffee-help-me-find-a-bug-in-my-code/</link>
            <pubDate>Fri, 17 Mar 2023 00:00:00 +0000</pubDate>
            <guid>https://karas.codes/posts/how-did-making-making-coffee-help-me-find-a-bug-in-my-code/</guid>
            <description>


                &lt;p&gt;I know what you&amp;rsquo;re thinking. Did that really happened? My answer is yes, it happened.&lt;/p&gt;
&lt;h2 id=&#34;context&#34;&gt;Context&lt;/h2&gt;
&lt;p&gt;It happened a couple of months after I started working in a team that developed browser extension. I got some bug to investigate related with one key feature of its extension.&lt;/p&gt;
&lt;p&gt;When I found a code that was the potential culprit of a bug, I just set breakpoints in the browser and started trying to incrementally move through the code to examine it.&lt;/p&gt;
&lt;p&gt;But I had no luck. I spent a big chunk of my time trying to trigger it in different ways… but still the corner case I wanted to find was hidden.&lt;/p&gt;
&lt;h2 id=&#34;coffee&#34;&gt;Coffee&lt;/h2&gt;
&lt;p&gt;After a couple of minutes I needed a quick break to make a cup of coffee and to think about other approaches that I could follow to find the culprit. But when I got back to my browser and IDE I spotted that the breakpoint was active! Something had triggered the correct code.&lt;/p&gt;
&lt;h2 id=&#34;solution&#34;&gt;Solution&lt;/h2&gt;
&lt;p&gt;It turned out that feature I was testing, was using &lt;code&gt;idle&lt;/code&gt; browser API. As a name says that API was allowing the user to track a device idle state. Inside a code I found an event handler responsible for doing the rest of the work. Solving a bug was super easy in the end.&lt;/p&gt;
&lt;p&gt;That history is still funny after couple years… I still can’t believe that I solved a bug by preparing a coffee :)&lt;/p&gt;

            </description>
        </item>
        
        
        
        <item>
            <title>Using the Blocking webRequest API with Manifest V3</title>
            <link>https://karas.codes/posts/how-to-use-blocing-web-request-api-with-manifest-v3/</link>
            <pubDate>Fri, 03 Mar 2023 00:00:00 +0000</pubDate>
            <guid>https://karas.codes/posts/how-to-use-blocing-web-request-api-with-manifest-v3/</guid>
            <description>


                &lt;p&gt;If you are on this page, you are probably extension developer that is in trouble. In this post I will try to help you introduce workaround that works.&lt;/p&gt;
&lt;h2 id=&#34;context&#34;&gt;Context&lt;/h2&gt;
&lt;p&gt;As you know a lot of APIs was removed or deprecated by introducing Manifest V3. It was advertised as change for good direction. As increased user privacy, better performance etc. Unfortunately by looking at how changes works in the runtime, what workarounds were created for a couple of problems and what changes were done since the announcing MV3, im not quite sure that this was change for good.&lt;/p&gt;
&lt;h2 id=&#34;declarative-net-request-api-as-a-cure&#34;&gt;Declarative net request api as a cure&lt;/h2&gt;
&lt;p&gt;We could reimplement our code in order to use &lt;code&gt;declarativeNetRequest&lt;/code&gt;, but this API won&amp;rsquo;t allow us to do everything we need - in the code we could implement action that is needed in a way that we want to.&lt;/p&gt;
&lt;h2 id=&#34;workaround&#34;&gt;Workaround&lt;/h2&gt;
&lt;p&gt;Are you developing enterprise and self-hosted browser extension? You are saved!&lt;/p&gt;
&lt;p&gt;According to the Google Chrome documentation (should work on Edge too) you are able to still use blocking version of &lt;code&gt;webRequest&lt;/code&gt; API.&lt;/p&gt;
&lt;p&gt;You just need to add &lt;code&gt;webRequestBlocking&lt;/code&gt; into the manifest permissions.&lt;/p&gt;
&lt;h2 id=&#34;are-there-any-drawbacks-of-that-approach&#34;&gt;Are there any drawbacks of that approach?&lt;/h2&gt;
&lt;p&gt;Unfortunately, they are&amp;hellip;&lt;/p&gt;
&lt;p&gt;Because of some &lt;a href=&#34;https://bugs.chromium.org/p/chromium/issues/detail?id=1338871&#34;&gt;bug&lt;/a&gt; in Chromium project we could not run that code locally (when using unpacked version of your extension). Extension must be deployed to your enterprise domain via policy.&lt;/p&gt;
&lt;p&gt;So testing your code could be quite tricky. I advise you to do it on internal version that is hidden from production environment and your customers. Apart from that everything works as before. Hope this API would be still available after sunsetting MV2 extensions.&lt;/p&gt;
&lt;p&gt;Other good news, Firefox claimed that they would be still maintaining this API.&lt;/p&gt;

            </description>
        </item>
        
        
        
        <item>
            <title>Using Conditional Breakpoints</title>
            <link>https://karas.codes/posts/using-conditional-breakpoints/</link>
            <pubDate>Sat, 21 Jan 2023 00:00:00 +0000</pubDate>
            <guid>https://karas.codes/posts/using-conditional-breakpoints/</guid>
            <description>


                &lt;p&gt;This post would cover another tip that could make debugging process way easier. Imagine that we have registered a listener for some browser API, and we want to test how it works. Sometimes our normal break point won&amp;rsquo;t stop the code execution. That&amp;rsquo;s why we could use &lt;strong&gt;conditional breakpoints&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;whats-conditional-breakpoint&#34;&gt;What&amp;rsquo;s conditional breakpoint?&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s just line of code marked as normal breakpoint, but with additional condition applied. Thanks to that approach our code will stop there only if condition would be fulfilled. Take a look at example shown below.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://karas.codes/conditional_breakpoint.png&#34; alt=&#34;Browser debugger with a conditional breakpoint on line 6 with the condition map !== undefined &amp;amp;&amp;amp; map !== null &amp;amp;&amp;amp; map.size &amp;gt; 0&#34; width=&#34;429&#34; height=&#34;197&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;
&lt;p&gt;Also in multithreaded languages e.g. like Java we could decide whether stop all threads or only one that is executing code for given class.&lt;/p&gt;
&lt;h2 id=&#34;when-we-should-use-it&#34;&gt;When we should use it?&lt;/h2&gt;
&lt;p&gt;We could use conditional breakpoints when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we want to filter out breakpoints we don&amp;rsquo;t want to observe that time&lt;/li&gt;
&lt;li&gt;we want to stop the code only in some specific cases&lt;/li&gt;
&lt;li&gt;to make sure that breakpoint for event listener would stop the code execution&lt;/li&gt;
&lt;/ul&gt;

            </description>
        </item>
        
        
        
        <item>
            <title>Debugging Manifest V3 Browser Extensions</title>
            <link>https://karas.codes/posts/debugging-browser-extension-based-on-manifest-version-3/</link>
            <pubDate>Thu, 19 Jan 2023 00:00:00 +0000</pubDate>
            <guid>https://karas.codes/posts/debugging-browser-extension-based-on-manifest-version-3/</guid>
            <description>


                &lt;p&gt;Developers are facing with debugging code on a daily basis. When developing browser extension that is using service worker inside it could be a little hard sometimes to debug it properly. In this article I will explain how make it in easier way.&lt;/p&gt;
&lt;h2 id=&#34;catching-actions-that-are-done-after-starting-a-service-worker&#34;&gt;Catching actions that are done after starting a service worker&lt;/h2&gt;
&lt;p&gt;I wanted to discover a specific case when our extension is doing some task or requests right after calling a service worker. In order to catch actions done there we could use a simple trick.&lt;/p&gt;
&lt;p&gt;In the script marked as dedicated to service worker (that applies to both JS and TS versions):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;background&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;service_worker&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;src/serviceWorker.ts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead of calling methods we want directly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// src/serviceWorker.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sum&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;y&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Result: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sum&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We could do:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// src/serviceWorker.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Delay in miliseconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;delay&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;15000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;setTimeout&lt;/span&gt;(() =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;y&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sum&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;x&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;y&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;console&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Result: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;sum&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}, &lt;span style=&#34;color:#a6e22e&#34;&gt;delay&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That approach will give us time on opening background page after injecting local version of our extension in the browser. Thanks to that we will be able to: check all logs, network requests, breakpoints from the start.&lt;/p&gt;
&lt;p&gt;Hope you would find this post useful!&lt;/p&gt;

            </description>
        </item>
        
        
    </channel>
</rss>