PageSourceSearch

https://shakacode.com/component---src-template-blog-article-tsx-co…ng-ferrum-index-mdx-e85e30918fde61bfa8a8.js

js shakacode.com collected 2026-10-04 00:27:46 UTC 46,873 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkgatsby_starter_default=self.webpackChunkgatsby_starter_default||[]).push([[2639],{79912:function(e,n,a){a.r(n),a.d(n,{Head:function(){return f},default:function(){return y}});var t=a(28453),s=a(96540);function l(e){const n=Object.assign({p:"p",a:"a",h2:"h2",span:"span",ul:"ul",li:"li",strong:"strong",h3:"h3",h4:"h4",ol:"ol"},(0,t.R)(),e.components);return s.createElement(s.Fragment,null,s.createElement(n.p,null,"In the ever-evolving landscape of web automation,\nRuby developers have long relied on the robust Selenium framework.\nBut for those seeking a more streamlined,\nlightweight approach,\na new contender has emerged:\n",s.createElement(n.a,{href:"https://github.com/rubycdp/ferrum"},"Ferrum"),"."),"\n",s.createElement(n.h2,{id:"ferrum-in-a-nutshell",style:{position:"relative"}},s.createElement(n.a,{href:"#ferrum-in-a-nutshell","aria-label":"ferrum in a nutshell permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Ferrum in a Nutshell"),"\n",s.createElement(n.p,null,"Ferrum,\naffectionately dubbed the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Headless Chrome Ruby API</code>'}}),",\nis a gem that allows Ruby programmers to interact with Chrome\nand\nChromium browsers in a simple,\nefficient,\nand\nprotocol-driven manner.\nUnlike Selenium,\nwhich relies on WebDriver\nand\nexternal drivers,\nFerrum leverages the Chrome DevTools Protocol (CDP) directly,\noffering several advantages:"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Headless by Default:"),"\nFerrum prioritizes headless automation,\nminimizing resource consumption\nand\nmaking it ideal for server-side tasks\nand\ntesting environments."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Ruby-Centric API:"),"\nDesigned with Ruby developers in mind,\nFerrum offers a clean,\nintuitive API that feels natural\nand\nfamiliar."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Raw Power of CDP:"),"\nBy accessing the CDP directly,\nFerrum unlocks the full potential of Chrome's capabilities,\nenabling control over various aspects like network,\nsecurity,\nand\nperformance."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Lightweight and Fast:"),"\nFerrum boasts a minimal footprint,\nmaking it ideal for projects requiring efficient resource utilization."),"\n"),"\n"),"\n",s.createElement(n.h2,{id:"working-with-ferrum",style:{position:"relative"}},s.createElement(n.a,{href:"#working-with-ferrum","aria-label":"working with ferrum permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Working with Ferrum"),"\n",s.createElement(n.h3,{id:"installation",style:{position:"relative"}},s.createElement(n.a,{href:"#installation","aria-label":"installation permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Installation"),"\n",s.createElement(n.p,null,"Add the below line to your Gemfile\nand\nexecute the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">bundle install</code>'}}),"."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">gem <span class="token string-literal"><span class="token string">"ferrum"</span></span>\n\n<span class="token operator">></span> bundle install</code></pre></div>'}}),"\n",s.createElement(n.p,null,"If you are writing a script,\nexecute the below command in your terminal to install\nthe ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ferrum</code>'}})," gem."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token operator">></span> gem install ferrum</code></pre></div>'}}),"\n",s.createElement(n.h3,{id:"where-ferrum-can-be-used",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#where-ferrum-can-be-used","aria-label":"where ferrum can be used permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Where ferrum can be used"),"\n",s.createElement(n.h4,{id:"web-testing",style:{position:"relative"}},s.createElement(n.a,{href:"#web-testing","aria-label":"web testing permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Web Testing"),"\n",s.createElement(n.p,null,"Ferrum simplifies writing comprehensive tests for web applications by letting\nyou control Chrome\nand\ninteract with its elements programmatically.\nYou can test user flows,\nverify pages,\nand\nvalidate functionalities.\nYou can run tests without a visible browser window,\nenhancing efficiency\nand\nresource usage.\nThis is particularly useful for CI/CD pipelines\nor\nlarge test suites."),"\n",s.createElement(n.p,null,"While Ferrum directly controls Chrome,\nit can be used within browser testing frameworks like Capybara to achieve\ncross-browser compatibility with other Chromium-based browsers like Edge\nand\nBrave."),"\n",s.createElement(n.p,null,"As shown in the screenshot below,\nlet's say you have a simple Rails application\nwith a ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">HomeController</code>'}})," rendering the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">index</code>'}})," action."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 750px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/77513e848a82ad29684d7933f2437338/f7616/ferrum-gem-demo.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 70.2127659574468%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB0klEQVR42q2RW2/aQBCF/et54J2/wOUJEO1DFSkSLxDVYOJigbFMU2OndQK+QHzb9dqnu1vRpk2D1CojfdrZXfvMzFlFMw5YqhZuVmt8MHdYmAF6769hOz62zgPsLz4+u3t825/gH5Lf8PwIpnPEZBVA3Rwxs05QzM0JO9XA7d0t3jk77PwCw6srBEGAxwcfh/0jz/dgjOHPIHmGKGHQtikMj2H1FVCecoanskZGKlBSIycUqGsQUiIvKJKU4HjKEB85MReIU57/IM0op0R4KhEcqUSJo4gLFSC0QFUxeN49aMng7Dxs7zws9A1uPupy1ZcW5osVz018Mmy49wHCuEAQZgiiXKLUvPWqqiRirJLDWMlFSxS8w4J3ylgluxWFJJTJCYhYZf4LJU1T5Hkuxeq6fuGTOKOUyFwUJYT89btzKJ1OB61WC+12G71eD4PBAN1uF+PxGMPhELPZDI1GA6PRCM1mE/1+H5dCEa9p2zaWyyXm8zk0TcNkMpFnhmHAdV3oug5VVeWdZVmXBcW4lNKfI58R+7OvtXx1gizLkCQJSu7vq4KiougkDEPppfjpOeJM+Lxer6UN0+lU7s/+vhB8bv6/8GqHly7/JxS8cby54HdAhS2mkt03twAAAABJRU5ErkJggg==\'); background-size: cover; display: block;"\n  ></span>\n  <img\n        class="gatsby-resp-image-image"\n        alt="ferrum gem demo"\n        title=""\n        src="/static/77513e848a82ad29684d7933f2437338/1d69c/ferrum-gem-demo.png"\n        srcset="/static/77513e848a82ad29684d7933f2437338/4dcb9/ferrum-gem-demo.png 188w,\n/static/77513e848a82ad29684d7933f2437338/
15ff7e/ferrum-gem-demo.png 375w,\n/static/77513e848a82ad29684d7933f2437338/1d69c/ferrum-gem-demo.png 750w,\n/static/77513e848a82ad29684d7933f2437338/f7616/ferrum-gem-demo.png 766w"\n        sizes="(max-width: 750px) 100vw, 750px"\n        style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n        loading="lazy"\n        decoding="async"\n      />\n  </a>\n    </span>'}}),"\n",s.createElement(n.p,null,"You enter the name\nand\nclick ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Submit</code>'}}),".\nIt redirects you to the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">HomeController</code>'}})," ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">show</code>'}})," page."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<span\n      class="gatsby-resp-image-wrapper"\n      style="position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 750px; "\n    >\n      <a\n    class="gatsby-resp-image-link"\n    href="/static/08e537a27bc60444bf147c3a7557b6cb/df56e/ferrum-gem-demo2.png"\n    style="display: block"\n    target="_blank"\n    rel="noopener"\n  >\n    <span\n    class="gatsby-resp-image-background-image"\n    style="padding-bottom: 38.82978723404255%; position: relative; bottom: 0; left: 0; background-image: url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABGUlEQVR42q2Py27CMBBF8/+/wScgQLBqxQapm4oi0QWE5mGXBggkDlGc16ntiqrqpl0w0tFcW547195yteYhTHh8WrMNJfvkTJop6hZ0B7VBlZpX2fAcNKwEv+h5scQ9y6jDO6YZMi+55IrccDqdORxTsrwgM8a2X0yP9opNnLOTBb5UbEWOL5TRhdGK4KNEnGq8vu+pa01Zlm4wlgc2fkQQ7fHfBLtAOh0LQ/yOMD2K3glCYc5f96H5WZKkFFeNV1yvxrChbVuqShtd03WtW9B1nUNrjV38V9k33mQyYTabMRqNWCwWjMdjx3w+ZzqdMhwOGQwGJk38PXTjp9GtPJvMYpPZ3jSN0/aR1VVVubT/SegMuXPd3fATBHFlBOBZXHIAAAAASUVORK5CYII=\'); background-size: cover; display: block;"\n  ></span>\n  <img\n        class="gatsby-resp-image-image"\n        alt="ferrum gem demo2"\n        title=""\n        src="/static/08e537a27bc60444bf147c3a7557b6cb/1d69c/ferrum-gem-demo2.png"\n        srcset="/static/08e537a27bc60444bf147c3a7557b6cb/4dcb9/ferrum-gem-demo2.png 188w,\n/static/08e537a27bc60444bf147c3a7557b6cb/5ff7e/ferrum-gem-demo2.png 375w,\n/static/08e537a27bc60444bf147c3a7557b6cb/1d69c/ferrum-gem-demo2.png 750w,\n/static/08e537a27bc60444bf147c3a7557b6cb/78797/ferrum-gem-demo2.png 1125w,\n/static/08e537a27bc60444bf147c3a7557b6cb/df56e/ferrum-gem-demo2.png 1188w"\n        sizes="(max-width: 750px) 100vw, 750px"\n        style="width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"\n        loading="lazy"\n        decoding="async"\n      />\n  </a>\n    </span>'}}),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Note:")),"\n",s.createElement(n.p,null,"To ensure you can access ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">/home</code>'}}),",\nadd the below routes to the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/routes</code>'}})," file."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">Rails<span class="token punctuation">.</span>application<span class="token punctuation">.</span>routes<span class="token punctuation">.</span>draw <span class="token keyword">do</span>\n  get <span class="token string-literal"><span class="token string">"home"</span></span> <span class="token operator">=></span> <span class="token string-literal"><span class="token string">"home#index"</span></span>\n  get <span class="token string-literal"><span class="token string">"submit"</span></span> <span class="token operator">=></span> <span class="token string-literal"><span class="token string">"home#show"</span></span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"You can test this page using the Ferrum gem by writing a system spec.\nFor this,\nyou must ensure the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ferrum</code>'}})," gem is installed in your Rails application."),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Create a ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">
1home_page_test.rb</code>'}})," file under the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">test/system</code>'}})," directory."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Add the code below to this file."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token keyword">require</span> <span class="token string-literal"><span class="token string">\'test_helper\'</span></span>\n\n<span class="token keyword">class</span> <span class="token class-name">HomePageTest</span> <span class="token operator">&lt;</span> ActionDispatch<span class="token double-colon punctuation">::</span>SystemTestCase\n  <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">setup</span></span>\n    <span class="token variable">@browser</span> <span class="token operator">=</span> Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span>\n  <span class="token keyword">end</span>\n\n  <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">teardown</span></span>\n    <span class="token variable">@browser</span><span class="token punctuation">.</span>quit\n  <span class="token keyword">end</span>\n\n  test <span class="token string-literal"><span class="token string">"visiting the homepage and interacting with elements"</span></span> <span class="token keyword">do</span>\n     <span class="token variable">@page</span> <span class="token operator">=</span> <span class="token variable">@browser</span><span class="token punctuation">.</span>create_page\n     <span class="token variable">@page</span><span class="token punctuation">.</span>goto <span class="token string-literal"><span class="token string">"http://localhost:3000/home"</span></span>\n\n     <span class="token comment"># Find an element using a CSS selector</span>\n     header <span class="token operator">=</span> <span class="token variable">@page</span><span class="token punctuation">.</span>at_css<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">\'h1\'</span></span><span class="token punctuation">)</span>\n     assert_equal <span class="token string-literal"><span class="token string">"Welcome to Rails!"</span></span><span class="token punctuation">,</span> header<span class="token punctuation">.</span>text\n\n     <span class="token comment"># Fill in a form and submit it</span>\n     input_field <span class="token operator">=</span> <span class="token variable">@page</span><span class="token punctuation">.</span>at_xpath<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"//*[@id=\'name\']"</span></span><span class="token punctuation">)</span>\n     input_field<span class="token punctuation">.</span>focus<span class="token punctuation">.</span>type<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"Sam Example"</span></span><span class="token punctuation">)</span>\n     <span class="token variable">@page</span><span class="token punctuation">.</span>at_xpath<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"/html/body/form/input[2]"</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span>click\n\n     <span class="token comment"># Assert the response</span>\n     assert <span class="token variable">@page</span><span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token keyword">include</span><span class="token operator">?</span><span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"Welcome Sam Example"</span></span><span class="token punctuation">)</span>\n  <span class="token keyword">end</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Run the spec in your terminal as below\nand\nit should pass."),"\n"),"\n"),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Note:"),"\nWhen working with Ferrum,\nyou need to start the rails server,\nwhile executing system specs."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">> demo_ferrum % rails s\n\n# on a new tab in the terminal run the system spec\n> demo_ferrum % rails test test/system/home_page_test.rb\n  Running 1 tests in a single process (parallelization threshold is 50)\n  Run options: --seed 22870\n\n  # Running:\n\n  .\n\n  Finished in 1.157573s, 0.8639 runs/s, 1.7278 assertions/s.\n  1 runs, 2 assertions, 0 failures, 0 errors, 0 skips</code></pre></div>'}}),"\n",s.createElement(n.p,null,"When you execute the spec,\na headless Chrome version is running.\nIf you don't want to run the spec in the headless version,\nyou need to pass ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">headless: false</code>'}})," to the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">new</code>'}})," method as shown:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token keyword">class</span> <span class="token class-name">HomePageTest</span> <span class="token operator">&lt;</span> ActionDispatch<span class="token double-colon punctuation">::</span>SystemTestCase\n  <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">setup</span></span>\n    <span class="token variable">@browser</span> <span class="token operator">=</span>
1 Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token symbol">headless</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">)</span>\n  <span class="token keyword">end</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.h4,{id:"web-scraping-and-crawling",style:{position:"relative"}},s.createElement(n.a,{href:"#web-scraping-and-crawling","aria-label":"web scraping and crawling permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Web Scraping and Crawling"),"\n",s.createElement(n.p,null,"Ferrum can navigate web pages,\nfind specific elements,\nand\nprogrammatically extract text,\nimages,\nor\nother data.\nThis can be helpful for market research,\ncompetitor analysis,\nor\nbuilding datasets."),"\n",s.createElement(n.p,null,"You can add a rake task for website scraping in your Rails application.\nLet's say you want to scrape ",s.createElement(n.strong,null,"Books to Scrape")," website."),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Create a file ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">scraping.rake</code>'}})," in the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">lib/tasks</code>'}})," directory."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Add the following code to the file."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token comment"># lib/tasks/scraping.rake</span>\n<span class="token comment"># This file is used for scraping websites using Ferrum</span>\n\nnamespace <span class="token symbol">:scraping</span> <span class="token keyword">do</span>\n  desc <span class="token string-literal"><span class="token string">"Crawl the Books To Scrape website"</span></span>\n  task <span class="token symbol">:book_to_scrape</span> <span class="token keyword">do</span>\n    browser <span class="token operator">=</span> Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span>\n\n    <span class="token keyword">begin</span>\n      page <span class="token operator">=</span> browser<span class="token punctuation">.</span>create_page\n      page<span class="token punctuation">.</span>go_to <span class="token string-literal"><span class="token string">"https://books.toscrape.com/"</span></span>\n\n      <span class="token comment"># Extract book titles and prices</span>\n      book_elements <span class="token operator">=</span> page<span class="token punctuation">.</span>css<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"article.product_pod"</span></span><span class="token punctuation">)</span>\n      books <span class="token operator">=</span> book_elements<span class="token punctuation">.</span>map <span class="token keyword">do</span> <span class="token operator">|</span>book_element<span class="token operator">|</span>\n        title <span class="token operator">=</span> book_element<span class="token punctuation">.</span>at_css<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"h3 a"</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span>text\n        price <span class="token operator">=</span> book_element<span class="token punctuation">.</span>at_css<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">
1"p.price_color"</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span>text\n        <span class="token punctuation">{</span> <span class="token symbol">title</span><span class="token operator">:</span> title<span class="token punctuation">,</span> <span class="token symbol">price</span><span class="token operator">:</span> price <span class="token punctuation">}</span>\n      <span class="token keyword">end</span>\n\n      puts books\n    <span class="token keyword">ensure</span>\n      browser<span class="token punctuation">.</span>quit\n    <span class="token keyword">end</span>\n  <span class="token keyword">end</span>  \n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Note:")),"\n",s.createElement(n.p,null,"The ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.css</code>'}})," function will return an Array of ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Node</code>'}})," objects.\nThe ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.at_css</code>'}})," will return the first node that matches the CSS.\nPlease go through the\n",s.createElement(n.a,{href:"https://github.com/rubycdp/ferrum?tab=readme-ov-file#finders"},"Finders"),"\nsection in the ",s.createElement(n.strong,null,"README")," of the gem.\nIt has a comprehensive list of all the functions available on the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">browser</code>'}}),"\nand\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">page</code>'}})," objects."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,"Execute the rake task in your terminal: ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rake scraping:book_to_scrape</code>'}}),".\nYou might see the following output in your terminal."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">> demo_ferrum % rake scraping:book_to_scrape\n {:title => "A Light in the ...", :price => "£51.77"}\n {:title => "Tipping the Velvet", :price => "£53.74"}\n {:title => "Soumission", :price => "£50.10"}\n {:title => "Sharp Objects", :price => "£47.82"}\n {:title => "Sapiens: A Brief History ...", :price => "£54.23"}\n {:title => "The Requiem Red", :price => "£22.65"}\n {:title => "The Dirty Little Secrets ...", :price => "£33.34"}\n {:title => "The Coming Woman: A ...", :price => "£17.93"}\n {:title => "The Boys in the ...", :price => "£22.60"}\n {:title => "The Black Maria", :price => "£52.15"}\n {:title => "Starving Hearts (Triangular Trade ...", :price => "£13.99"}\n {:title => "Shakespeare\'s Sonnets", :price => "£20.66"}\n {:title => "Set Me Free", :price => "£17.46"}\n {:title => "Scott Pilgrim\'s Precious Little ...", :price => "£52.29"}\n {:title => "Rip it Up and ...", :price => "£35.02"}\n {:title => "Our Band Could Be ...", :price => "£57.25"}\n {:title => "Olio", :price => "£23.88"}\n {:title => "Mesaerion: The Best Science ...", :price => "£37.59"}\n {:title => "Libertarianism for Beginners", :price => "£51.33"}\n {:title => "It\'s Only the Himalayas", :price => "£45.17"}</code></pre></div>'}}),"\n"),"\n"),"\n",s.createElement(n.h4,{id:"other-automation-tasks",style:{position:"relative"}},s.createElement(n.a,{href:"#other-automation-tasks","aria-label":"other automation tasks permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Other Automation Tasks:"),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Automate repetitive tasks:")),"\n",s.createElement(n.p,null,"Here's a detailed breakdown of how Ferrum empowers\nyou to automate various tasks across different websites."),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Filling Forms")),"\n",s.createElement(n.p,null,"Imagine automatically filling online forms with pre-defined information,\nlike customer details\nor\nshipping addresses.\nNo more tedious typing,\ntypos,\nor\nwasted time!\nWhether Chrome,\nFirefox,\nor\nChromium-based,\nFerrum adapts to handle forms across various platforms."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Submitting Requests")),"\n",s.createElement(n.p,null,"Automate submitting data requests,\nfeedback forms,\nor\neven registration forms on multiple websites with Ferrum\nand\nlet the browser handle the tedious clicks\nand\nnavigation."),"\n",s.createElement(n.p,null,"If you want to submit reports\nor\nforms at specific times\nor\nintervals,\nFerrum can be integrated 
1with\nscheduling tools to automate recurring tasks."),"\n"),"\n"),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Create PDF reports from web pages:")),"\n",s.createElement(n.p,null,"With Ferrum,\nyou can generate PDF reports from web pages in several ways,\ndepending on your desired level of control\nand\ncomplexity."),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Using Chromium's built-in PDF printing")),"\n",s.createElement(n.p,null,"This is the simplest method and requires minimal code.\nUse the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">pdf</code>'}})," method on the Ferrum browser instance.\nYou can create a rake task as below:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby"><span class="token comment"># lib/tasks/pdf.rake</span>\n\ndesc <span class="token string-literal"><span class="token string">"Convert to PDF using Ferrum"</span></span>\ntask <span class="token symbol">:print_to_pdf</span> <span class="token keyword">do</span>\n  browser <span class="token operator">=</span> Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span>\n  browser<span class="token punctuation">.</span>go_to<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">"https://books.toscrape.com/"</span></span><span class="token punctuation">)</span>\n\n  pdf_data <span class="token operator">=</span> browser<span class="token punctuation">.</span>pdf<span class="token punctuation">(</span><span class="token symbol">margin</span><span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">)</span>\n\n  <span class="token builtin">File</span><span class="token punctuation">.</span>open<span class="token punctuation">(</span><span class="token string-literal"><span class="token string">\'report.pdf\'</span></span><span class="token punctuation">,</span> <span class="token string-literal"><span class="token string">\'wb\'</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">|</span>file<span class="token operator">|</span> file<span class="token punctuation">.</span>write<span class="token punctuation">(</span>pdf_data<span class="token punctuation">)</span> <span class="token punctuation">}</span>\n<span class="token keyword">end</span></code></pre></div>'}}),"\n"),"\n"),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Control browser extensions:")),"\n",s.createElement(n.p,null,"While Ferrum doesn't directly control extensions within the browser,\nyou can preload the extensions using the ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">:extensions</code>'}})," option."),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">browser <span class="token operator">=</span> Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span>\n  <span class="token symbol">extensions</span><span class="token operator">:</span> <span class="token punctuation">[</span>\n    <span class="token string-literal"><span class="token string">"/path/to/extension1.crx"</span></span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token symbol">source</span><span class="token operator">:</span> <span class="token string-literal"><span class="token string">"window.secret = \'top\'"</span></span> <span class="token punctuation">}</span><span class="token punctuation">,</span>\n    <span class="token string-literal"><span class="token string">"/path/to/extension2.crx"</span></span>\n  <span class="token punctuation">]</span>\n<span class="token punctuation">)</span></code></pre></div>'}}),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Screenshots:")),"\n",s.createElement(n.p,null,"The Ferrum gem offers a comprehensive screenshot\nfeature with various options to capture specific web page portions\nor\nviewports."),"\n",s.createElement(n.p,null,"Use the screenshot method on your ",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Ferrum::Browser</code>'}})," object:"),"\n",s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="ruby"><pre class="language-ruby"><code class="language-ruby">desc <span class="token string-literal"><span class="token string">"Take screenshots"</span></span>\ntask <span class="token symbol">:screenshots</span> <span class="token keyword">do</span>\n  browser <span class="token operator">=</span>
1 Ferrum<span class="token double-colon punctuation">::</span><span class="token class-name">Browser</span><span class="token punctuation">.</span><span class="token keyword">new</span>\n\n  <span class="token keyword">begin</span>\n    page <span class="token operator">=</span> browser<span class="token punctuation">.</span>create_page\n    page<span class="token punctuation">.</span>go_to <span class="token string-literal"><span class="token string">"https://books.toscrape.com/"</span></span>\n     \n    <span class="token comment"># take screenshot of full page</span>\n    page<span class="token punctuation">.</span>screenshot<span class="token punctuation">(</span><span class="token symbol">path</span><span class="token operator">:</span> <span class="token string-literal"><span class="token string">"books.png"</span></span><span class="token punctuation">,</span> <span class="token symbol">full</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span>\n  <span class="token keyword">ensure</span>\n    browser<span class="token punctuation">.</span>quit\n  <span class="token keyword">end</span>   \n<span class="token keyword">end</span></code></pre></div>'}}),"\n",s.createElement(n.p,null,"This case is handy to debug the issue with flaky specs."),"\n",s.createElement(n.p,null,"You can pass a few more options to the screenshot method.\nA few of them are:"),"\n",s.createElement(n.ol,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">path</code>'}}),": Specify the path to save the screenshot as a file."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">encoding</code>'}}),": Choose between :binary (default) or :base64 for returning the image data."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">format</code>'}}),': Select the image format ("jpeg" or "png").'),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">quality</code>'}}),": Set the JPEG quality (0-100)."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">full</code>'}}),": Capture the entire page (default is visible viewport)."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">selector</code>'}}),": Target a specific element within the viewport for capture."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">area</code>'}}),": Define a custom area for the screenshot using coordinates (x, y, width, height)."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">scale</code>'}}),": Zoom in/out the page before capturing."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">background_color</code>'}}),": Set a custom background color for the screenshot."),"\n"),"\n"),"\n"),"\n"),"\n",s.createElement(n.h2,{id:"why-choose-ferrum",style:{position:"relative"}},s.createElement(n.a,{href:"#why-choose-ferrum","aria-label":"why choose ferrum permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Why Choose Ferrum?"),"\n",s.createElement(n.p,null,"Sure, other gems handle automation, but Ferrum offers a unique blend of benefits:"),"\n",s.createElement(n.ul,null,"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Simplicity:"),"\nIts Ruby-flavored API feels natural\nand\nintuitive,\nmaking even complex tasks a breeze."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Speed:"),"\nForget clunky overhead.\nFerrum's direct CDP connection translates to blazing-fast execution,\nespecially for repetitive tasks."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Power:"),"\nUnleash the full potential of Chrome DevTools.\nFerrum grants access to features often hidden behind WebDriver layers,\nopening a world of possibilities."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Flexibility:"),"\nNeed a hybrid of head full\nand\nheadless?\nFerrum can handle it.\nWant to customize the browser window size or user-agent?\nNo problem.\nIts flexibility lets you bend automation to your will."),"\n"),"\n",s.createElement(n.li,null,"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Lightweight:"),"\nDitch the bulky dependencies\nand\nenjoy a gem with a minimal footprint,\nfreeing up resources for your actual code."),"\n"),"\n"),"\n",s.createElement(n.h2,{id:"does-ferrum-uses-capybara",style:{position:"relative"}}
1,s.createElement(n.a,{href:"#does-ferrum-uses-capybara","aria-label":"does ferrum uses capybara permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Does Ferrum uses Capybara?"),"\n",s.createElement(n.p,null,"No,\nFerrum does not use Capybara under the hood.\nWhile it works well with Capybara,\nthey differ in their approach\nand\ngoals:"),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Ferrum")," is designed as a low-level,\npure-Ruby Chrome/Chromium driver\nand\noffers ",s.createElement(n.strong,null,"direct communication with Chrome DevTools Protocol (CDP)"),"\nfor fine-grained control\nand\nflexibility.\nIt is primarily used for complex browser automation tasks,\nweb scraping,\nperformance profiling,\nand\nbrowser scripting."),"\n",s.createElement(n.p,null,s.createElement(n.strong,null,"Capybara")," acts as a higher-level,\nabstraction layer for browser testing.\nIt supports multiple drivers,\nincluding WebDriver\nand\nFerrum (through the Cuprite gem).\nIt is focused on simulating user interactions\nand\ntesting web applications in various scenarios."),"\n",s.createElement(n.p,null,s.createElement(n.a,{href:"https://github.com/rubycdp/cuprite"},"Cuprite"),"\nis a driver for Capybara that specifically uses Ferrum.\nIt allows you to leverage Capybara's familiar API with\nFerrum's underlying headless Chrome capabilities.\nThis is ideal if you already use Capybara for testing\nand\nwant to benefit from Ferrum's performance\nand\nflexibility."),"\n",s.createElement(n.h2,{id:"conclusion",style:{position:"relative"}},s.createElement(n.a,{href:"#conclusion","aria-label":"conclusion permalink",className:"anchor before"},s.createElement(n.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Conclusion"),"\n",s.createElement(n.p,null,"Whether you're a seasoned automation veteran\nor\na curious newbie,\nFerrum deserves a spot in your Ruby toolbox.\nIts intuitive API,\nraw power,\nand\nflexible approach to headless Chrome make it a compelling choice\nfor conquering any web automation challenge.\nSo,\nsaddle up,\npartner,\nand\nlet Ferrum guide you through the wild west of web automation!"),"\n",s.createElement(n.p,null,"I have created a Rails application for the above steps.\nPlease refer to this\n",s.createElement(n.a,{href:"https://github.com/shakacode/demo_ferrum"},"repository"),"."))}var r=function(e){void 0===e&&(e={});const{wrapper:n}=Object.assign({},(0,t.R)(),e.components);return n?s.createElement(n,e,s.createElement(l,e)):l(e)},o=a(5588),c=a(65427),i=a(20504),p=a(43397),u=a(61942);const m=e=>e.replace(/\/+$/,""),d=(e,n)=>n?""+e+(n.startsWith("/")?n:"/"+n):e,g=(e,n)=>d(m(e),n),h=(e,n)=>d((e=>"undefined"!=typeof window?window.location.origin:m(e))(e),n),k=(e,n)=>{const a=(0,o.d)(n);return a?g(e,a):(e=>g(e,"/shakacode-og.png"))(e)},b=e=>{let{data:n,location:a,children:t}=e;const{frontmatter:l}=n.mdx,{siteUrl:r}=n.site.siteMetadata,o=h(r,a.pathname);return s.createElement(s.Fragment,null,s.createElement(c.A,null),s.createElement(i.A,{header:s.createElement(u.r,{breadcrumb:l.title}),main:s.createElement(s.Fragment,null,s.createElement(u.c,{body:t,title:l.title,author:l.author,date:l.date,link:o,categories:l.categories,featuredImage:l.featuredImage,showFeaturedImage:l.showFeaturedImage}),s.createElement(p.LN,null))}))};function y(e){return s.createElement(b,e,s.createElement(r,e))}const f=e=>{let{data:n,location:a}=e;const{frontmatter:t,excerpt:l}=n.mdx,{siteMetadata:r}=n.site,{siteUrl:o,title:c,description:i}=r,p=((e,n,a)=>e.excerpt||n||a)(t,l,i),u=k(o,t.featuredImage),m=g(o,a.pathname);return s.createElement(s.Fragment,null,s.createElement("title",null,t.title+" | "+c),s.createElement("link",{rel:"canonical",href:m}),s.createElement("meta",{name:"description",content:p}),s.createElement("meta",{property:"og:title",content:t.title}),s.createElement("meta",{property:"og:description",content:p}),s.createElement("meta",{property:"og:type",content:"article"}),s.createElement("meta",{property:"og:url",content:m}),s.createElement("meta",{property:"og:image",content:u}),s.createElement("meta",{name:"image",content:u}),s.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),s.createElement("meta",{name:"twitter:title",content:t.title}),s.createElement("meta",{name:"twitter:description",content:p}),s.createElement("meta",{name:"twitter:image",content:u}))}}}]);
2//# sourceMappingURL=component---src-template-blog-article-tsx-content-file-path-src-posts-headless-chrome-automation-in-rails-using-ferrum-index-mdx-e85e30918fde61bfa8a8.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.