<?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: codepoetn</title>
    <description>The latest articles on Forem by codepoetn (@codepoetn).</description>
    <link>https://forem.com/codepoetn</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%2F490897%2Fd245d103-3048-4196-b741-6adc1e53f7ea.webp</url>
      <title>Forem: codepoetn</title>
      <link>https://forem.com/codepoetn</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/codepoetn"/>
    <language>en</language>
    <item>
      <title>Skeptical about "AI coding agents?" Here's how you save 10-30 hours of your dev time by implementing enterprise SSO in 10 minutes using Claude Code Scalekit Auth Stack Plugins.</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Tue, 24 Mar 2026 04:23:56 +0000</pubDate>
      <link>https://forem.com/codepoetn/skeptical-about-ai-coding-agents-heres-how-you-save-10-30-hours-of-your-dev-time-by-3bei</link>
      <guid>https://forem.com/codepoetn/skeptical-about-ai-coding-agents-heres-how-you-save-10-30-hours-of-your-dev-time-by-3bei</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/scalekit-inc/add-enterprise-sso-to-your-nextjs-app-in-minutes-using-claude-code-scalekit-5edg" class="crayons-story__hidden-navigation-link"&gt;Add Enterprise SSO to Your Next.js App in Minutes Using Claude Code &amp;amp; Scalekit&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/scalekit-inc"&gt;
            &lt;img alt="Scalekit Inc logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F9274%2Fccba0584-6e3b-4c00-8c89-609f4feb2a3e.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/saif_shines" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F17823%2F91f9c351-1a4b-4849-a4b7-80a136b6be3f.jpg" alt="saif_shines profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/saif_shines" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Saif 
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Saif 
                
              
              &lt;div id="story-author-preview-content-3392482" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/saif_shines" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F17823%2F91f9c351-1a4b-4849-a4b7-80a136b6be3f.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Saif &lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/scalekit-inc" class="crayons-story__secondary fw-medium"&gt;Scalekit Inc&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/scalekit-inc/add-enterprise-sso-to-your-nextjs-app-in-minutes-using-claude-code-scalekit-5edg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/scalekit-inc/add-enterprise-sso-to-your-nextjs-app-in-minutes-using-claude-code-scalekit-5edg" id="article-link-3392482"&gt;
          Add Enterprise SSO to Your Next.js App in Minutes Using Claude Code &amp;amp; Scalekit
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sso"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sso&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/claudecode"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;claudecode&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/nextjs"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;nextjs&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/fullstack"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;fullstack&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/scalekit-inc/add-enterprise-sso-to-your-nextjs-app-in-minutes-using-claude-code-scalekit-5edg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/scalekit-inc/add-enterprise-sso-to-your-nextjs-app-in-minutes-using-claude-code-scalekit-5edg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            9 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>sso</category>
      <category>claudecode</category>
      <category>nextjs</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>Optimised Google SecOps - Thwart Cyber Threats In Style</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Thu, 05 Feb 2026 18:41:18 +0000</pubDate>
      <link>https://forem.com/codepoetn/optimised-google-secops-thwart-cyber-threats-in-style-an8</link>
      <guid>https://forem.com/codepoetn/optimised-google-secops-thwart-cyber-threats-in-style-an8</guid>
      <description>&lt;p&gt;Taking cognizance of the costs of cyberattacks, &lt;a href="https://www.statista.com/statistics/1319682/annual-increase-in-it-security-budget-worldwide/" rel="noopener noreferrer"&gt;enterprises increased their annual IT security budget by 5.7 percent&lt;/a&gt;. If you’re heading security at your org, you would know how hard it is to get the budgets approved by any CFO. Anyway, it’s probably ‘the good times’ for security professionals; finally, cybersecurity is getting its fair share of attention.&lt;/p&gt;

&lt;p&gt;What’s fuelling this attention? The cost of not paying attention. &lt;/p&gt;

&lt;p&gt;Who wouldn’t be extra cautious knowing that the cost of cybercrimes will surpass 15.63 trillion by 2029?&lt;/p&gt;

&lt;p&gt;You read that right. 15.63 Trillion!!!&lt;/p&gt;

&lt;p&gt;If you don’t plan to contribute to that number, you better amplify your cybersecurity arsenal. Shh, I’m letting you in on a secret…enterprise CIO &amp;amp; CISO leaders often turn to &lt;a href="https://cloud.google.com/security/products/security-operations" rel="noopener noreferrer"&gt;Google SecOps&lt;/a&gt; (formerly known as ‘Chronicle’) to streamline their security operations.&lt;/p&gt;

&lt;p&gt;“Why Google SecOps,” you ask. &lt;/p&gt;

&lt;p&gt;Well, an IDC study revealed that Google SecOps clients command as much as $13.50 million in additional revenue per year on average. &lt;/p&gt;

&lt;p&gt;That spike is (in)directly attributed to SecOps because it gives organizations secure innovative muscles. &lt;/p&gt;

&lt;p&gt;Ah, by the way, Google SecOps is not the only tool where the money is flowing. When we earlier mentioned a 5.7% spike in annual security budgets, did you wonder where that extra fund for cybersecurity would go? Where your peer CIOs &amp;amp; CISOs are investing? A short answer would be, everything that bolsters enterprise security; both established and emerging security areas are under the radar; To be precise, Security Information and Event Management (&lt;strong&gt;SIEM&lt;/strong&gt;) &amp;amp; Security Orchestration, Automation, and Response (&lt;strong&gt;SOAR&lt;/strong&gt;) tools.&lt;/p&gt;

&lt;p&gt;More specifically, for 60% of enterprises Cloud Security is a top priority, followed by Data Security (59%), Identity Threat Detection &amp;amp; Response (47%), Infrastructure Protection (36%), and Automated Security Control Assessment (37%) as other critical fronts where security investments are being channelized. SOC teams are betting big on tools like Splunk, Microsoft Sentinel, and Google SecOps.&lt;/p&gt;

&lt;p&gt;Read this insight, written by &lt;a href="https://linkedin.com/in/codepoetn" rel="noopener noreferrer"&gt;Nishant Choudhary&lt;/a&gt;, to the very end to understand how optimizing Google SecOps can help you flex your organizational innovation muscles. SecOps does the heavy-lifting and handles majority of your security concerns in a cost-effective manner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/codepoetn" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Meet Nishant, the tech writer&lt;/a&gt;
 &lt;/p&gt;

&lt;p&gt;Let’s start with a primer on Google SecOps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Google SecOps? — A short primer for beginners.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Google SecOps, at the core, is a Gen-AI-led SIEM &amp;amp; SOAR platform, aka cloud service that lets you proactively collect, aggregate, normalize, correlate/analyze, auto-detect, investigate, and respond to security telemetry data i.e., logs, events, and incidents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyhwgw9gcibtlq5cjur2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyhwgw9gcibtlq5cjur2.png" alt="Source: Google SecOps Data Ingestion &amp;amp; Processing Workflow" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google SecOps platform provides customers with a suite of security tools and features that are either natively built into the platform or can be integrated to extend the platform’s capabilities. &lt;/p&gt;

&lt;p&gt;For example, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To ingest log data, you have inbuilt Google’s SecOps SIEM which will collect raw data from forwarders, or you can use 3rd party connectors and webhooks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To normalize the data streamed/forwarded to your SIEM tool in order to analyze it, you get a set of 800+ parsers accessible at your fingertips.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small, big, and many Fortune 500 companies rely on Google SecOps for a unified view of their SIEM, SOAR, and threat intelligence data. Some of the notable names in their clientele include Etsy, Groupon, and Pfizer. &lt;/p&gt;

&lt;p&gt;One of the main reasons why enterprises are flocking to Google SecOps is its pricing model and log data storage capability. In a report, clients cited an &lt;a href="https://services.google.com/fh/files/misc/idc-business-value-of-google-secops.pdf" rel="noopener noreferrer"&gt;average increase of 283% in data ingestion capabilities&lt;/a&gt; when they switched to Google SecOps compared to their last SIEM vendor platform. &lt;/p&gt;

&lt;p&gt;Obviously, the economy of scale positions Google SecOps to gain a pricing edge over comparatively smaller players. Hence, depending on your use cases and the scale of security operations, you might be able to save a lot by making the switch to Google SecOps. &lt;/p&gt;

&lt;p&gt;Wait, there is more to it.&lt;/p&gt;

&lt;p&gt;Wouldn’t your eyes sparkle if we told you that you could save way more by optimizing your Google SecOps platform?&lt;/p&gt;

&lt;p&gt;Yeah, that’s possible. You can further slash your SIEM costs. &lt;/p&gt;

&lt;p&gt;“How?” you ask.&lt;/p&gt;

&lt;p&gt;Well, first let’s get ourselves brushed up with prominent Google SecOps features and components so that we can explain on a high level how you may save more while improving your security posture by optimizing Google SecOps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dismantling Google SecOps Platform — One part at a time.
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, Google SecOps provides your SOC team with the tools for SIEM &amp;amp; SOAR. Holistically speaking, they help you with the following capabilities-&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Ingestion/Collection, Parsing, and Enrichment
&lt;/h3&gt;

&lt;p&gt;Data can be ingested using-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linux &amp;amp; Windows Forwarders, which can be installed on the client’s end.&lt;/li&gt;
&lt;li&gt;BindPlane agent, which can be managed using the BindPlane OP Management console.&lt;/li&gt;
&lt;li&gt;Google Security Operations SIEM ingestion service’s APIs.&lt;/li&gt;
&lt;li&gt;Data Feeds from static cloud storage like AWS S3, or 3rd party APIs like Okta.&lt;/li&gt;
&lt;li&gt;Google Cloud Account, of course.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can input both-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raw/processed log data from your network devices, servers, or security software or devices installed on-premise, cloud-based solutions, or&lt;/li&gt;
&lt;li&gt;Alerts from other SIEM solutions, EDRs, or Ticketing systems using SecOps’ SOAR connectors and Webhooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any ingested data needs to be formatted as a Unified Data Model (UDM) structure, which is nothing but a standard structured schema that Google SecOps uses to store security data. This helps build semantic consistency when the influx of data is in varied formats from varied sources. And with the UDM approach, it’s easier to write platform-agnostic security rules. &lt;/p&gt;

&lt;p&gt;But how do you format the raw data as UDM? &lt;/p&gt;

&lt;p&gt;That’s where parsers come in. &lt;/p&gt;

&lt;p&gt;You can use pre-built parsers if your log type source is available in Google SecOps’ pool of 800+ parsers, or you can use your own custom parsers.&lt;/p&gt;

&lt;p&gt;Lastly, once your UDM data is ready, Google Security Operation services enrich your data from various sources by adding contextual data about artifacts using-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entity graph and merging&lt;/li&gt;
&lt;li&gt;Safe Browsing threat list&lt;/li&gt;
&lt;li&gt;Geolocation data&lt;/li&gt;
&lt;li&gt;WHOIS data&lt;/li&gt;
&lt;li&gt;VirusTotal data&lt;/li&gt;
&lt;li&gt;Google Cloud Threat Intelligence (GCTI) data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Threat Detection
&lt;/h3&gt;

&lt;p&gt;When your security data is ready to be consumed by Google Security Operations’ downstream systems, you can use YARA-L language to configure Rules to trigger alerts for threat detection, and use Google SecOps innate ability to correlate vast number of suspicious security Indicators of Compromise (IOC). &lt;/p&gt;

&lt;p&gt;Google provides a very rich set of rules-related features to put you in control of how proactively you want to deal with security threats— from Rules Dashboard for viewing rules and their previous versions to rules editor for managing rules, configuring their run frequency, archiving them, dealing with rule detection limits, and performing context-aware risk scoring and severity analytics; you get everything needed for ‘threat detection’ off-the-shelf.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nvrk53zpsit8vzcu2jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nvrk53zpsit8vzcu2jj.png" alt="Source: Google SecOps Rules Dashboard" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Threat Investigation &amp;amp; Intelligence
&lt;/h3&gt;

&lt;p&gt;What happens after alerts get triggered or your set rule-based events/incidents are detected? Maybe, you can respond, or you can investigate further. The good news is that Google SecOps gets it. They provide tools to perform forensics-grade investigation on your raw log data, UDM data, or context-enriched data. You can use timestamps, regular expressions, boolean operators, and various filters available for the involved entities under different investigative views— user, asset, IP address, Files, and Hash views. Each of these views has enormous data to perform root cause analysis of security incidents. &lt;/p&gt;

&lt;p&gt;Nevertheless, as an extra layer of security, Google SecOps Applied Threat Intelligence (ATI)  helps you discover any occurrence of IOC matches that are curated by Mandiant threat intelligence. At the core, these too are alerts contextualized by Yara-L using Curated Detection. &lt;/p&gt;

&lt;h3&gt;
  
  
  Threat Response
&lt;/h3&gt;

&lt;p&gt;Lastly, all the detection and investigation pave the way for threat prevention or mitigation by safeguarding your enterprise security fencing, aka defense system. The threat response is mainly about playbooks— triggers, actions, and flows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Triggers are a way of activating a playbook based on threat detection &amp;amp; investigative insights.&lt;/li&gt;
&lt;li&gt;Actions are a set of tasks that need to be completed in response to the threat.&lt;/li&gt;
&lt;li&gt;Flow defines how a set action gets implemented.
You can even use remote agents and custom code and integrations to create a robust threat response system. For example, you can use Google Security Operations’ Agent to execute private actions on your remote site in response to an incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gemini Stitched Right Into The Google SecOps Fabric
&lt;/h2&gt;

&lt;p&gt;Gemini comes integrated into your Google SecOps platform. You can use it to generate UDM search queries, write custom YARA-L rules for threat detection, use it as your threat analytics research partner, create playbooks, or just understand Alerts and the Actions that can be performed to mitigate the threats.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/codepoetn" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Follow Nishant (author of the post) on LinkedIn&lt;/a&gt;
 &lt;/p&gt;

&lt;h2&gt;
  
  
  Reimagining Your Enterprise Security by Optimizing Google Security Operations
&lt;/h2&gt;

&lt;p&gt;All this is cool, and now it’s time for the crux of this blog. Google SecOps is all great, but can you further optimize it for cost efficiency while squeezing everything that it has to offer? Yup, you can.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inflating Data Orchestration Costs
&lt;/h3&gt;

&lt;p&gt;IT Telemetry data storage and forwarding volume is a major cost factor in SIEM &amp;amp; SOAR tools. Disparate IT systems within an enterprise (including Cloud &amp;amp; on-premise) generate tons of data, then be it from EDR consoles, firewall logs, vulnerability scans, employee activity, or IAM tools. Terabytes of data get generated on a daily basis depending on your organization’s scale. But not all of this data is security critical. Some of it is sheer noise. Calling it ‘junk’ won’t hurt anyone’s sentiments. Forwarding, processing, or storing this data in raw or UDM format is just a waste of your resources. These leakages can quickly inflate to jaw-dropping costs, often north of 6,7 figures. &lt;/p&gt;

&lt;p&gt;You may fix such leakages in the following ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Extended Set of Parsers Solve The Data Usability Challenges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are platforms that help you with telemetry data orchestration. They provide managed Google SecOps services. You may even find vendors who provide pre-built connectors and integrations to complement Google’s 800+ connectors. This saves you enough time and money that you would have alternatively invested in designing parsers for normalizing raw log data into UDM format from all your edge nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Relevance-based Data Orchestration Solves The Volume Challenge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The influx of AI-powered security solutions can help you significantly reduce data ingestion volumes. Obviously, not all the data would make sense. Some are less critical, some are sensitive data. Context-aware volume reduction solution would ensure that only security-value-worthy data gets forwarded to Google SecOps, and the less critical data gets filtered or pushed to cheaper storage alternatives, maybe even dumped on-premise in your own data lake. More relevant data translates into faster attack/anomaly detection and prepares the ground for proactive response/remediation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. System-aware and Context-aware Security Data Enrichment &amp;amp; Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Managed SIEM solutions not only separate the less critical data to improve the data usability and insights quality but also enrich UDM-modeled data. This facilitates SOC teams later to effectively leverage Google SecOps search capabilities to deeply investigate the events, and subsequently configure comprehensive response triggers to filter out less critical events and channel the team’s effort towards those incidents that impact the business bottom line. This translates to enhanced talent productivity, faster threat mitigation, faster shipping of new features to the market, and ultimately more revenue while optimizing your Cybersecurity budget utilization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Enhances Interoperability Among Your Entire SOC Stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another good perk of  weaving your security fabric with a managed SIEM solution is the flexibility and freedom it provides to your SOC team. Today, most of the companies have an evolving infrastructure. The bigger it grows in size, the lesser the freedom to experiment with new platforms. &lt;/p&gt;

&lt;p&gt;Often, you get pigeonholed into doing the best you can with your existing vendors because the cost of switching overcasts the benefits of switching. &lt;/p&gt;

&lt;p&gt;But not anymore with managed SIEM solutions; your SOC team will not find themselves in vendor lock-in situations.&lt;/p&gt;

&lt;p&gt;You can anytime make the switch to any platform that best serves your goals- then be it Microsoft Sentinel Google SecOps or any other platform.&lt;/p&gt;

&lt;p&gt;Ready to leap into futuristic and proactive security?&lt;/p&gt;

&lt;p&gt;Keep rocking!&lt;/p&gt;

</description>
      <category>secops</category>
      <category>devsecops</category>
      <category>gcp</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Adding Firefox Extensions With Selenium In Python</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Mon, 26 Jul 2021 06:59:26 +0000</pubDate>
      <link>https://forem.com/codepoetn/adding-firefox-extensions-with-selenium-in-python-5hbn</link>
      <guid>https://forem.com/codepoetn/adding-firefox-extensions-with-selenium-in-python-5hbn</guid>
      <description>&lt;p&gt;Modern browsers are equipped with all sorts of functionalities, i.e., from bookmarks to GPS location tracking, developer tools, and more. Almost all the modern web browsers have immense capabilities – Firefox has inbuilt screenshot capabilities, Opera has a free VPN, and Edge comes with in-built support for displaying ebooks with EPUB extension. Though browsers like Firefox, Chrome, and others are majorly used for web browsing, the fact is that Add Ons (or extensions) in Firefox provide additional power to the web browser! The same rule of thumb is also applicable to other browsers like Chrome, Edge, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-14-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-14-1.png" alt="pasted image 0 (14)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additional add-ons, plugins, extensions are required to extend or customize browser functionalities, boost productivity, and suit specific requirements of users and developers. Test automation engineers that use Selenium test automation can also benefit from browser extensions like normal end-users. In fact, testers often need to automate the testing of these extensions itself 🙂&lt;/p&gt;

&lt;p&gt;The catch is that the extensions installed on the Firefox browser present on the local machine will not be available when you fire up a Firefox instance using Gecko Driver and Selenium WebDriver. In this part of the &lt;a href="https://www.lambdatest.com/learning-hub/python-tutorial?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-26072021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium Python tutorial&lt;/a&gt;, we deep dive into adding extensions in Firefox using Selenium WebDriver and Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Firefox WebExtensions API?
&lt;/h2&gt;

&lt;p&gt;In Sept 2015, Mozilla started signing and validating every extension to ensure that the third-party extensions enable Firefox customization without sacrificing security or exposing users vulnerable to malware. Mozilla deprecated XPCOM and XUL-based add-ons and adapted a new extensions API (i.e., WebExtensions API).&lt;/p&gt;

&lt;p&gt;New extensions API is compatible with the model used by Opera, Chrome, and other latest browsers. Thus, a Firefox extension developer can easily develop and manage cross-browser extensions.&lt;/p&gt;

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

&lt;p&gt;XPI is a cross-platform installer module file. It’s the same as zip files and can be accessed using any archive/compression program. XPI installation files are in use by Firefox, SeaMonkey, and Thunderbird. It is used for installing a web browser plugin, addons, extensions, etc.&lt;/p&gt;

&lt;p&gt;XPI add ons can be installed by simply dragging and dropping into any open Firefox browser window. Mozilla uses XPInstall to read the installation instructions contained in the XPI file, which are later executed for the installation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-13-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-13-1.png" alt="pasted image 0 (13)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Chromium-based browsers like Chrome, Opera, and Edge use CRX files as extension installers. Safari uses SAFARIEXTZ. CRX files can’t be used to install extensions in Mozilla. XPIs can’t be used in Chromium-based browsers. However, the underlying API is the same for all these browsers, due to which maintenance of extensions is pretty easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add extensions in Firefox using Selenium WebDriver and Python?
&lt;/h2&gt;

&lt;p&gt;Now that we have covered the fundamentals of extensions in Firefox, let’s look at how to add Firefox extensions using Selenium WebDriver and Python. Let’s look at the various approaches available to leverage Selenium and Firefox extensions for &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-26072021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium web automation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using install_addon API of Selenium WebDriver to add Firefox extensions using Python
&lt;/h3&gt;

&lt;p&gt;The install_addon method of the Selenium WebDriver takes two input arguments – path to the desired Firefox extension and a Boolean value which indicates whether installation of the extension is temporary (or not).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; : Let’s download the XPIs of the target Firefox extensions.&lt;/p&gt;

&lt;p&gt;You can point your cursor to the “ADD to Firefox button,” right-click and copy the XPI link. Then, open it in a new tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-12-1-1024x575.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-12-1-1024x575.png" alt="pasted image 0 (12)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can find a dedicated XPI download link by opening the extension’s landing page in a different browser than Firefox.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-11-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-11-1.png" alt="pasted image 0 (11)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For demonstration, we’re downloading the following Firefox extensions – “&lt;a href="https://addons.mozilla.org/firefox/downloads/file/3658190/vpn_master-0.1.4-an+fx.xpi" rel="noopener noreferrer"&gt;VPN Master&lt;/a&gt;” and “&lt;a href="https://addons.mozilla.org/firefox/downloads/file/3733151/ghostery_privacy_ad_blocker-8.5.5-an+fx.xpi" rel="noopener noreferrer"&gt;Ghostery Privacy Ad Blocker.&lt;/a&gt;” The XPI downloader link for VPN Master is available below the green-colored button (visible in the below image) if opened using Chrome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; : Here’s how the &lt;a href="https://www.selenium.dev/selenium/docs/api/py/_modules/selenium/webdriver/firefox/webdriver.html#WebDriver.install_addon" rel="noopener noreferrer"&gt;webdriver’s install_addon function&lt;/a&gt; is implemented for installing install the add-on in Mozilla:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def install_addon(self, path, temporary=None):
    # Usage: driver.install_addon('/path/to/firebug.xpi')
    # ‘self’ refers to the “Webdriver” class
    # 'path' is absolute path to the addon that will be installed
    payload = {"path": path}
    if temporary:
        payload["temporary"] = temporary
    # The function returns an identifier of the installed addon.
    # This identifier can later be used to uninstall installed addon.
    return self.execute("INSTALL_ADDON", payload)["value"]  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s use this &lt;em&gt;install_addon&lt;/em&gt; method to install the Ghostery Firefox extension temporarily.&lt;/p&gt;

&lt;p&gt;Shown below is the Python implementation that uses Selenium WebDriver and install_addon method to install the Ghoserty plugin. The first two lines import the dependent libraries. I have added sufficient comments in the try, except, and finally python code block for easing the code walkthrough process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filename: FFExt.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Fire a remote Firefox instance using geckodriver.
&lt;/span&gt;    &lt;span class="c1"&gt;# You need to have Geckodriver in the same directory as the automation testing script OR
&lt;/span&gt;    &lt;span class="c1"&gt;# you need to add it in the "path" environment variable OR 
&lt;/span&gt;    &lt;span class="c1"&gt;# you need to know the full path to the geckodriver executable file and use it as:
&lt;/span&gt;    &lt;span class="c1"&gt;# driver = webdriver.Firefox(executable_path=r'your\path\geckodriver.exe') 
&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Firefox&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# path to your downloaded Firefox addon extension XPI file
&lt;/span&gt;
    &lt;span class="n"&gt;extension_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;G:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;jsalert&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;vpnxpi&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;ghostery_privacy_ad_blocker-8.5.5-an+fx.xpi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="c1"&gt;# using webdriver's install_addon API to install the downloaded Firefox extension
&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;install_addon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temporary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Opening the Firefox support page to verify that addon is installed
&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about:support&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# xpath to the section on the support page that lists installed extension
&lt;/span&gt;
    &lt;span class="n"&gt;addons&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//*[contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add-ons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and not(contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# scrolling to the section on the support page that lists installed extension
&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;execute_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arguments[0].scrollIntoView();&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# introducing program halt time to view things, ideally remove this when performing test automation in the cloud using LambdaTest
&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success. Yayy!!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="c1"&gt;# exiting the fired Mozilla Firefox selenium webdriver instance
&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;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# End Of Script
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;isActive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Test Execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the test by triggering the following command on the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python FFExt.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the execution output of the Firefox extension example that used Selenium WebDriver:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-10-1-1024x238.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-10-1-1024x238.png" alt="pasted image 0 (10)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As seen from the execution snapshot, the Ghostery plugin icon appears at the top right corner. The Firefox extension installed using the install_addon method (of Selenium WebDriver) is enabled by default.&lt;/p&gt;

&lt;p&gt;Let’s try this: Comment out the following line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.install_addon(extension_path, temporary=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As seen in the below snapshot, the Ghostery extension is no longer a part of the installed extensions since it was installed temporarily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-9-1-1024x222.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-9-1-1024x222.png" alt="pasted image 0 (9)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using PyTest to add Firefox extensions using Selenium and Python
&lt;/h3&gt;

&lt;p&gt;PyTest is an open-source Python testing framework that is more extensively in place of the PyUnit framework. You can use PyTest for writing small tests and complex functional tests for python-based applications/libraries. On Github, PyTest clocks 7.4k+ stars. You can check out our existing blog for a quick recap on &lt;a href="https://www.lambdatest.com/blog/test-automation-using-pytest-and-selenium-webdriver/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-26072021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium web automation in Python using PyTest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File Name: FFExt.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;

&lt;span class="c1"&gt;# Pytest fixture is used when before running the test you need to execute some code
&lt;/span&gt;
&lt;span class="nd"&gt;@pytest.fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;FFExt&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Firefox&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;extension_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;G:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;jsalert&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;vpnxpi&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;ghostery_privacy_ad_blocker-8.5.5-an+fx.xpi&lt;/span&gt;&lt;span class="sh"&gt;"&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;install_addon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extension_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;temporary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about:support&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;addons&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//*[contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add-ons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and not(contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&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;execute_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arguments[0].scrollIntoView();&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;addons1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_elements_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//*[contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add-ons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and not(contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))]/following-sibling::*[1]/*[2]/*/*[1]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# a list is created to return names of all the installed addons
&lt;/span&gt;        &lt;span class="n"&gt;addonsList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;addon&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;addons1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;addonsList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&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;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;addonsList&lt;/span&gt;

&lt;span class="c1"&gt;# This is the test function that will ASSERT whether addon is present in the list of installed add-ons returned by the FFExt function.
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_addon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FFExt&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ghostery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ghostery – Privacy Ad Blocker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;ghostery&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;FFExt&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;isActive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test by triggering the following command on the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pytest FFExt.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the execution snapshot, which indicates that one test was successful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-8-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-8-1.png" alt="pasted image 0 (8)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: For every python project, pytest is the perfect choice for a reliable and maintainable testing architecture. For a quick overview on getting started with pytest, check out the video below from &lt;a href="https://www.youtube.com/channel/UCCymWVaTozpEng_ep0mdUyw" rel="noopener noreferrer"&gt;LambdaTest YouTube Channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;@&lt;a href="https://youtu.be/0ldd7v6j1Po" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using pre-loaded Firefox extensions and FirefoxProfile in Selenium WebDriver
&lt;/h3&gt;

&lt;p&gt;FirefoxProfile is a collection of settings, extensions, and customizations done on top of the Firefox browser. You can create several Firefox profiles to tailor-make the look &amp;amp; feel of the browser as per your preferences.&lt;/p&gt;

&lt;p&gt;To add Firefox extensions in Selenium using FirefoxProfile, please follow the below-mentioned steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; : Create a Firefox profile. Before doing so, you need to close all the active Firefox windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; : Press “win + R” to open the Run dialog window. Type “firefox.exe -P” and press OK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-7-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-7-1.png" alt="pasted image 0 (7)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt; : Now, click on the Create Profile button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-6-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-6-1.png" alt="pasted image 0 (6)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt; : Click Next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-5-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-5-1.png" alt="pasted image 0 (5)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt; : Enter a name for your new Firefox profile. Copy path to the destination folder (this will be required later). Click Finish to create the profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-4-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-4-1.png" alt="pasted image 0 (4)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt; : Launch Firefox with your newly created profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-3-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-3-1.png" alt="pasted image 0 (3)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt; : Add Ghostery Addon to this profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-2-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-2-1.png" alt="pasted image 0 (2)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s write a PyTest script to check if the Ghostery extension is installed when we launch the created Firefox profile in a remotely-controlled Firefox instance using Selenium Python.&lt;/p&gt;

&lt;p&gt;Existing Firefox profile can be loaded in Selenium webdriver using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webdriver.FirefoxProfile("\\path to the new Firefox profile’s folder")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filename: FFExt_method_2.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;

&lt;span class="nd"&gt;@pytest.fixture&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;FFExt2&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# the value you pass to parameter should be the name of folder which represents your target Firefox profile, you created earlier
&lt;/span&gt;    &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;FirefoxProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;G:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;7m1dwmtw.FFExt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Firefox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;about:support&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;addons&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//*[contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add-ons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and not(contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&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;execute_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arguments[0].scrollIntoView();&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;addons&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;addons1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_elements_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//*[contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Add-ons&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and not(contains(text(),&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;))]/following-sibling::*[1]/*[2]/*/*[1]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;addonsList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;addon&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;addons1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;addonsList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&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;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;addonsList&lt;/span&gt;

&lt;span class="c1"&gt;# this is the test function that will assert whether addon is present in the list of installed addons returned by FFExt function.
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_addon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FFExt2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ghostery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ghostery – Privacy Ad Blocker&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;ghostery&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;FFExt2&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;isActive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the following command on the terminal to trigger the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pytest FFExt_method_2.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the execution snapshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-1-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F06%2Fpasted-image-0-1-2.png" alt="pasted image 0 (1)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Extensions, especially VPN extensions, are often required to test how your application would perform across different geographies. Also, if you’ve implemented an adBlocker detection technology in your web application, then you need to install adBlocker extensions to check if your adBlocker detection technology is effective.&lt;/p&gt;

&lt;p&gt;In this part of the Selenium Python tutorial, we had a look at two different mechanisms to install addons in Selenium-controlled Firefox instances. Talking of extensions, we hope you already have LambdaTest chrome extension installed to test applications on the go. LambdaTest is a stellar tool for all your Selenium web automation requirements in the cloud. Do check out &lt;a href="https://www.lambdatest.com/lt-browser?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-26072021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;LT Browser&lt;/a&gt; and test applications across 50+ mobile screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Testing!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>python</category>
      <category>automation</category>
    </item>
    <item>
      <title>CircleCI Vs. GitLab: Choosing The Right CI/CD Tool</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Mon, 15 Mar 2021 08:14:19 +0000</pubDate>
      <link>https://forem.com/codepoetn/circleci-vs-gitlab-choosing-the-right-ci-cd-tool-3mj3</link>
      <guid>https://forem.com/codepoetn/circleci-vs-gitlab-choosing-the-right-ci-cd-tool-3mj3</guid>
      <description>&lt;p&gt;He is a gifted driver. Famed for speed, reverse J, and drifts. He can breeze through the Moscow and Mexico traffic without sweating a drop. Of course, no one gets cracking on Bengaluru roads 😛 But despite being so adept behind the wheels, he sometimes fails to champ the street races. Screeching tyres buzz in his head doesn’t let him sleep at times. I wish to tell him it’s not always about the driver, sometimes it’s the engine. That’s what happens when the right dev talent uses wrong, inefficient, incompatible &lt;a href="https://www.lambdatest.com/learning-hub/cicd?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;CI/CD tools&lt;/a&gt;. The DevOps technologies you chose can abruptly break or smoothly accelerate your software development cycle. This article explores the Ford &amp;amp; the Ferrari of the CI/CD world in detail, CircleCI vs. GitLab, to help you pick the right one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is CI/CD important?
&lt;/h2&gt;

&lt;p&gt;Modern software development approaches prioritize automating repetitive processes. ‘Lean, modular, iterative’ development is the new mantra of the dev community.&lt;/p&gt;

&lt;p&gt;CI/CD tools help in boosting ROI by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cutting costs.&lt;/li&gt;
&lt;li&gt;Speeding up time-to-market. Check how Financial Times &lt;a href="https://dzone.com/articles/the-roi-of-automated-testing" rel="noopener noreferrer"&gt;optimized the test cycle&lt;/a&gt; from about 10 days to less than a day.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Winning &amp;amp; retaining customers. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Streamlining the process of integrating independently developed software modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continuously testing application components independently as well as in an integrated state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continuously delivering new features as an integrated application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;According to &lt;a href="https://www.marketsandmarkets.com/Market-Reports/automation-testing-market-113583451.html" rel="noopener noreferrer"&gt;marketsandmarkets&lt;/a&gt;, QA automation testing is growing at a whopping 18% CAGR and is estimated to hit USD 28.8 Bn in 2024. The upsurge in the adoption of automation tools further bolsters the belief in CI/CD development approach. Can there be any smoke without a fire?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How CI/CD Works?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCICD-Workflow-1024x371.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCICD-Workflow-1024x371.png" alt="CICD Workflow" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re new to CI/CD, you must be thinking, “okay! I get the benefits, but how is all this implemented under the hood?”. Basically,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You use a hooked CI tool (hooks are a way to listen for change requests in the repository constantly) to your code repository.&lt;/li&gt;
&lt;li&gt;As soon as you try pushing the code to the repository, CI scripts get triggered. These scripts are lines of code in Python, C#, or any scripting language of your choice. The CI scripts build the application with newly pushed code and checks for any defects by subjecting it to automated unit tests &amp;amp; integration test scripts. These tests can be functional and non-functional. If there are errors, CI tools can be configured to alert the responsible authorities automatically.&lt;/li&gt;
&lt;li&gt;If the new code passes all tests, it is pushed to the continuous delivery stage and subsequently to the continuous deployment stage. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each stage of CI/CD is critically dependent on robust automation tests. In short, continuous testing is the backbone of the entire CI/CD pipeline. Follow these &lt;a href="https://www.lambdatest.com/blog/16-best-practices-of-ci-cd-pipeline-to-speed-test-automation/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;CI/CD best practices&lt;/a&gt; to harvest optimum benefits out of it.&lt;/p&gt;

&lt;p&gt;Now having answered what CI/CD pipeline is and highlighting the three obvious benefits of using DevOps tools, let’s briefly list some of the popular open-source and commercial CI/CD tools. Then we jump to the meat of this article, i.e., nose-to-nose comparison of CircleCI vs. GitLab.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are some of the most popular CI/CD tools?
&lt;/h2&gt;

&lt;p&gt;Jenkins is the jack of all things in CI/CD. It’s server-based &amp;amp; open-sourced. Using &lt;a href="https://www.lambdatest.com/learning-hub/jenkins?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Jenkins&lt;/a&gt;, you can automate almost the entire SDLC, everything from development &amp;amp; integration to testing, delivery, and deployment.&lt;/p&gt;

&lt;p&gt;TeamCity, CircleCI, Bamboo, Codeship, GoCD, GitLab, Semaphore are some other &lt;a href="https://www.lambdatest.com/blog/27-best-ci-cd-tools/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;popular CI/CD tools&lt;/a&gt; every DevOps engineer can play around with. Some of these are open-sourced, some commercially managed-solutions. Other than these, a DevOps guy would also have following gears up his sleeves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration automation tools

&lt;ul&gt;
&lt;li&gt;Ansible, Chef, Puppet, SolarWinds, CFEngine&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Container runtimes &amp;amp; orchestration tools

&lt;ul&gt;
&lt;li&gt;Docker, Kubernetes, Amazon ECS, Containers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  CircleCI Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCircleCI-Overview-1024x523.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCircleCI-Overview-1024x523.png" alt="CircleCI Overview" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is CircleCI?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://circleci.com/" rel="noopener noreferrer"&gt;CircleCI&lt;/a&gt;, like GitLab, is a modern CI/CD solution. This tool automates the “build, test, deploy workflow of an SDLC.” CircleCI can be used in the cloud as a SaaS tool with an option to run self-hosted runners for better supervising security aspects. Alternatively, you may also consider installing the CircleCI platform on your private server and have 100% control over it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How CircleCI works?
&lt;/h3&gt;

&lt;p&gt;CircleCI integrates with your code version control system, say GitHub or Bitbucket. Now, every time a developer pushes code to the repository, CircleCI creates a pipeline to process the code and test it against pre-scripted test-cases at various stages.&lt;/p&gt;

&lt;p&gt;CircleCI automatically runs this newly committed code in an isolated container or a virtual machine. Suppose the new code fails any predefined tests. In that case, CircleCI can be configured to notify your authorized team-mates so that appropriate action, say debugging, code revision, or code roll-back, can be initiated. And if the committed code successfully passes the pipeline, it gets pushed to your target staging or deployment environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are CircleCI Orbs?
&lt;/h3&gt;

&lt;p&gt;CircleCI orbs are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Condensed lines of reusable build config script.&lt;/li&gt;
&lt;li&gt;Shareable packages.&lt;/li&gt;
&lt;li&gt;Open-sourced and helps in speeding up CI/CD setup.&lt;/li&gt;
&lt;li&gt;Reduce the complexity and number of code lines you need to write for integrating your stack with the CI/CD pipeline. &lt;a href="https://circleci.com/docs/2.0/orb-intro/#benefits-of-using-orbs" rel="noopener noreferrer"&gt;Here’s a demo&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Noteworthy CircleCI features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Custom build environments &amp;amp; language support.

&lt;ul&gt;
&lt;li&gt;CircleCI can be configured to imitate your target deployment environment by configuring your pipeline execution environment using a Docker image or a LINUX/Windows/macOS virtual machine(VM).&lt;/li&gt;
&lt;li&gt;You can use a pre-built docker image provided by CircleCI, or you may choose your own Docker Hub image as the runtime environment.&lt;/li&gt;
&lt;li&gt;CircleCI pre-installs Android SDK, NDK, and other dependencies and enables you to build and test Android apps on a Linux VM.&lt;/li&gt;
&lt;li&gt;It supports a wide range of languages, including PHP, Python, Java, Javascript, ReactNative, RoR, Elixir, Scala, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Cloud, as well as Self-hosted CI/CD solution.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;As already discussed, CircleCI can be leveraged to orchestrate CI/CD pipeline either in the CircleCI’s cloud-hosted computes or, you can also implement CI/CD by running CircleCI on your infrastructure. This would give you complete authority to control functionalities and maintenance work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note-&lt;/strong&gt; macOS environment is limited to CircleCI’s cloud-hosted solution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highly extensible with integrations.

&lt;ul&gt;
&lt;li&gt;You can integrate CircleCI with AWS cloud ecosystem, Azure, DeployHub, Cloud Foundry, Google Cloud, OpenShift, Serverless, and several other environments/platforms to deploy your application. &lt;/li&gt;
&lt;li&gt;For testing, you can integrate CircleCI with platforms like LambdaTest.&lt;/li&gt;
&lt;li&gt;Find the full set of integrations &lt;a href="https://circleci.com/integrations/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Security and Performance

&lt;ul&gt;
&lt;li&gt;With CircleCI, you have application-level security and isolated runtime environment security.&lt;/li&gt;
&lt;li&gt;CircleCI is SOC II, and fedRamp certified.&lt;/li&gt;
&lt;li&gt;If your CI/CD pipeline implemented using CircleCI fails, you can SSH into your failed build and quickly debug it. &lt;/li&gt;
&lt;li&gt;Effectively uses caching to speed-up builds.&lt;/li&gt;
&lt;li&gt;Minimal setup overheads.&lt;/li&gt;
&lt;li&gt;CircleCI Orbs speeds-up CI/CD pipeline setup process.&lt;/li&gt;
&lt;li&gt;Single config.yml file contains all configuration details in a declarative style.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who uses CircleCI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Facebook, Kickstarter, Spotify, Lyft, Coinbase, Expedia, and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FGitLab-Overview-1024x477.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FGitLab-Overview-1024x477.png" alt="GitLab Overview" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is GitLab CI/CD?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://about.gitlab.com/" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt; positions itself as a SaaS-based holistic DevSecOps platform. What does that mean? It means it is a web-based git repository that allows you to plan your software and manage the entire development &amp;amp; operations cycle from managing source code to issue tracking, code integration, continuous testing, delivery, and deployment. It attempts to eliminate toolchain complexities involved in agile development methodology. In short, GitLab is a complete ecosystem for DevSecOps. For brevity and fair comparison, let’s limit ourselves to a niche GitLab product, i.e., GitLab CI/CD.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are GitLab CI/CD and GitLab Runner?
&lt;/h3&gt;

&lt;p&gt;GitLab CI/CD is a UI based web application that manages your projects or builds. It is also accessible through APIs. GitLab Runner processes your builds, i.e., runner applications execute the code in .gitlab-ci.yml configuration file. It runs the script by working in tandem with GitLab CI/CD via an API interface. Runners can run tests in any language across platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  How GitLab CI/CD works?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need to install and register a &lt;a href="https://docs.gitlab.com/runner/install/" rel="noopener noreferrer"&gt;runner&lt;/a&gt; for your project. Define your CI/CD jobs in a structured order and with well-defined actions if certain conditions are met while executing these jobs. Save this YAML file as .gitlab-ci.yml file in the root directory of your project.&lt;/li&gt;
&lt;li&gt;When you push config files to your repository, the runner runs these specified jobs.&lt;/li&gt;
&lt;li&gt;Usually, a GitLab CI/CD pipeline would contain four stages – build, test, staging, and production. If your code commit passes all these stages, it is successfully delivered/deployed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related Read: How to build an &lt;a href="https://www.lambdatest.com/blog/automated-testing-pipeline-with-gitlab-ci-cd-and-selenium/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Automated Testing Pipeline With GitLab CI/CD &amp;amp; Selenium Grid&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Noteworthy GitLab CI/CD features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multi-environment, multi-platform, multi-language.

&lt;ul&gt;
&lt;li&gt;GitLab CI/CD can be used to execute your build scripts on any platform that supports GO, including Windows, macOS, Unix, etc. It works with any language of your choice, including PHP, Python, Java, C, Ruby, etc.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;GitLab CI/CD Cloud vs. Self-hosted.

&lt;ul&gt;
&lt;li&gt;You can use GitLab cloud, i.e., gitlab.com, or you can self-host it. You can self-host it on your infrastructure, including on a bare-metal server or in Kubernetes on a public cloud, totally up to you.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Integrations

&lt;ul&gt;
&lt;li&gt;GitLab CI can be used with GitHub, BitBucket, or any other GIT based server.&lt;/li&gt;
&lt;li&gt;GitLab platform can be used with Jenkins CI too.&lt;/li&gt;
&lt;li&gt;HipChat, Slack, Auth0, SAML, Bitbucket, Vault, and several other integrations are available to streamline project lifecycle management.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Security &amp;amp; performance

&lt;ul&gt;
&lt;li&gt;Autoscaling, autoDevOps, parallel builds, and container registry features aim to improve the performance of GitLab CI/CD.&lt;/li&gt;
&lt;li&gt;GitLab provides SAST, DAST, Dependency scanning, fuzz testing, secret detection, and license compliance features for delivering highly secure applications.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who uses GitLab?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thomson Reuters, Siemens, HotJar, Nvidia, Goldman Sachs, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  CircleCI Vs. GitLab: Ratings
&lt;/h2&gt;

&lt;p&gt;Automation saves so much time. What do nerds do with the extra time? We debate which tool is better—just kidding. We channelize the extra time at hand in doing more productive work and growing company revenue. But a DevOps team isn’t a DevOps team if they haven’t discussed which CI/CD tools are better, easy to use, and efficient. CircleCI vs. GitLab is one such hot topic in the automation community. Both CircleCI &amp;amp; GitLab were launched around the same time in 2011. Let’s evaluate their strengths &amp;amp; shortcomings:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does the StackShare, G2 community have to say?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do you know G2 awards &lt;a href="https://www.g2.com/compare/circleci-vs-gitlab" rel="noopener noreferrer"&gt;4.4 stars&lt;/a&gt; to both GitLab &amp;amp; CircleCI? Just like GitHub stars, &lt;a href="https://stackshare.io/stackups/circleci-vs-gitlab" rel="noopener noreferrer"&gt;StackShares stack counts&lt;/a&gt; reflect the popularity of technology. CircleCI boasts around 7.4k stacks, while GitLab enjoys 31.1k stacks. Besides, GitLab as well as GitLab CI are open-source technologies and have garnered &lt;a href="https://github.com/gitlabhq/gitlabhq" rel="noopener noreferrer"&gt;22k+ stars on GitHub&lt;/a&gt;. Wait, this is not a reflection of how good GitLab is at CI/CD. These numbers reflect overall popularity. CircleCI is primarily “a niche-focused continuous integration tool” while GitLab wears multiple hats, including “version control &amp;amp; code collaborator.”&lt;/p&gt;

&lt;p&gt;CircleCI fans on StackShare are gaga about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub integration&lt;/li&gt;
&lt;li&gt;Easy Setup&lt;/li&gt;
&lt;li&gt;Fast build&lt;/li&gt;
&lt;li&gt;Competitive price&lt;/li&gt;
&lt;li&gt;Slack Integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitLab fans on StackShare cherishes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-hosted&lt;/li&gt;
&lt;li&gt;Open-source&lt;/li&gt;
&lt;li&gt;Community edition&lt;/li&gt;
&lt;li&gt;Familiar interface&lt;/li&gt;
&lt;li&gt;Easy setup&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CircleCI Vs. GitLab: Version Control System &amp;amp; Integrations
&lt;/h2&gt;

&lt;p&gt;A major differentiating factor between the two is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CircleCI works in integration with any version control system (VCS), say GitHub or bitbucket. CircleCI can be integrated with 50+ tools &amp;amp; services, including Slack and LambdaTest.&lt;/li&gt;
&lt;li&gt;GitLab provides out-of-the-box, in-built Git VCS, but it can also be used with GitHub for 400 free CI pipeline minutes. Beyond that, a user needs to upgrade plans. GitLab CI/CD can be used for Bitbucket cloud as well. GitLab chatOps enables working with CI/CD from slack chat interface. Plus, it can work with 160+ other tools and platforms, including LambdaTest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How this impacts your choice of CI/CD tools?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main intent behind implementing CI/CD pipelines is optimizing workflows. If your CI/CD tool natively supports the source control hosting service you’re using or external tools you want to integrate, then managing &amp;amp; addressing tickets would be easier and quicker. If you have to wait for days to solve issues, then the automation purpose is diluted. Both the tools provide flexibility in choosing your repository hosting but being an all-in-one solution, GitLab would have the edge over CircleCI as the learning curve gets shorter when you’ve to learn only one tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  CircleCI Vs. GitLab: Parallel &amp;amp; Distributed Builds
&lt;/h2&gt;

&lt;p&gt;Both CircleCI &amp;amp; GitLab can speed up the CI/CD pipeline processes by executing jobs in parallel. CircleCI workflow achieves this by running each build in an isolated containerized environment. In GitLab, you can configure the YAML file to perform parallel operations based on runner availability.&lt;/p&gt;

&lt;p&gt;Distributed job execution means horizontally scaling builds based on stages to multiple machines. CircleCI’s SaaS version distributes by default to several builder machines and is subject to availability, and there might not be any job queue. If you’re using the self-hosted CircleCI version, CircleCI still provides all the tools in-built to manage your clusters. GitLab too supports distributed scaling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container Environments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker Container Registry &amp;amp; Docker CI Runner comes pre-integrated with GitLab CI and avails complete CI/CD container workflow. Circle CI supports container build environments and runs each build in an isolated environment reset after every run. This translates into easy-identification of environment-born bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maintenance Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All GitLab plans except the free version have a next business day support system. CircleCI provides premium support for customers who need it, and for others, it provides email-support. For free tier users, community support is available. Cloud CI plan or CircleCI is fully automated and doesn’t need any maintenance service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hosting, Platform, Language, API, Plugin Support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitLab CI is available over the web and can run builds on any platform supporting GO, i.e., Windows, Unix, and macOS. It supports all major scripting and test automation languages, including Java, PHP, Ruby, C, Python. CircleCI is a cross-platform CI/CD solution; it supports Windows, macOS, managed cloud hosting, and you may even self-host on your dedicated infrastructure. Like GitLab, CircleCI supports all popular scripting technologies.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;FEATURE&lt;/th&gt;
&lt;th&gt;CIRCLECI&lt;/th&gt;
&lt;th&gt;GITLAB CI/CD&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;VCS INTEGRATION&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GITHUB, BITBUCKET&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IN-BUILT VCS&lt;/td&gt;
&lt;td&gt;NO&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DEBUGGING&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;NO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FREE-TIER&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CONTINUOUS INTEGRATION&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CONTINUOUS DEPLOYMENT&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MAINTENANCE&lt;/td&gt;
&lt;td&gt;EMAIL, PREMIUM, COMMUNITY&lt;/td&gt;
&lt;td&gt;COMMUNITY, NEXT BUSINESS DAY SUPPORT, PRIORITY SUPPORT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PARALLEL &amp;amp; DISTRIBUTED BUILDS&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;APIs&lt;/td&gt;
&lt;td&gt;RESTful&lt;/td&gt;
&lt;td&gt;RESTful, GRAPHQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SCHEDULING&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;USING CRON LIKE SETUP, YES&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CONTAINER/ DOCKER&lt;/td&gt;
&lt;td&gt;YES&lt;/td&gt;
&lt;td&gt;SHIPS WITH DOCKER&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUPPORT&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;td&gt;REGISTRY&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  CONCLUSION: Integrating CI/CD Tool With LambdaTest
&lt;/h2&gt;

&lt;p&gt;As you would have noticed, I referred to this comparison as Ford Vs. Ferrari. It was for a reason. Both the tools are equally good for streamlining your SDLC and implementing CI/CD for business agility. What is best suited to you is dependent on the tools you wish to integrate them with. LambdaTest &lt;a href="https://www.lambdatest.com/support/docs/gitlab-ci-integration-with-lambdatest/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;cloud Selenium Grid&lt;/a&gt; allows easy integration with both CircleCI and &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-15032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;GitLab&lt;/a&gt;. Evaluate wisely before coming to a decision. Wrong tools can push developer productivity in the valley; the right compatible tools can peak it. For automation testing, the LamdaTest platform has got your back; pick your CI/CD tool, and integrate it with LambdaTest.&lt;/p&gt;

</description>
      <category>circleci</category>
      <category>gitlab</category>
      <category>cicd</category>
      <category>devops</category>
    </item>
    <item>
      <title>How To Get Page Source In Selenium Using Python?</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Tue, 02 Mar 2021 08:03:26 +0000</pubDate>
      <link>https://forem.com/codepoetn/how-to-get-page-source-in-selenium-using-python-46a2</link>
      <guid>https://forem.com/codepoetn/how-to-get-page-source-in-selenium-using-python-46a2</guid>
      <description>&lt;p&gt;Retrieving the page source of a website under scrutiny is a day-to-day task for most test automation engineers. Analysis of the page source helps eliminate bugs identified during regular website UI testing, functional testing, or security testing drills. In an extensively complex application testing process, automation test scripts can be written in a way that if errors are detected in the program, then it automatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;saves that particular page’s source code.&lt;/li&gt;
&lt;li&gt;notifies the person responsible for the URL of the page.&lt;/li&gt;
&lt;li&gt;extracts the HTML source of a specific element or code-block and delegates it to responsible authorities if the error has occurred in one particular independent HTML WebElement or code block.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an easy way to trace, fix logical and syntactical errors in the front-end code. In this article, we first understand the terminologies involved and then explore how to get the page source in Selenium WebDriver using Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is An HTML Page Source?
&lt;/h2&gt;

&lt;p&gt;In non-technical terminology, it’s a set of instructions for browsers to display info on the screen in an aesthetic fashion. Browsers interpret these instructions in their own ways to create browser screens for the client-side. These are usually written using HyperText Markup Language (HTML), Cascading Style Sheets (CSS) &amp;amp; Javascript.&lt;/p&gt;

&lt;p&gt;This entire set of HTML instructions that make a web page is called page source or HTML source, or simply source code. Website source code is a collection of source code from individual web pages.&lt;/p&gt;

&lt;p&gt;Here’s an example of a Source Code for a basic &lt;a href="https://pynishant.github.io/page-source-selenium.html" rel="noopener noreferrer"&gt;page&lt;/a&gt; with a title, form, image &amp;amp; a submit button.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Page Source Example - LambdaTest&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;h2&amp;gt;Debug selenium testing results : LambdaTest&amp;lt;/h2&amp;gt;

&amp;lt;img src="https://cdn.lambdatest.com/assetsnew/images/debug-selenium-testing-results.jpg" alt="debug selenium testing" width="550" height="500"&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;form action="/"&amp;gt;
  &amp;lt;label for="debug"&amp;gt;Do you debug test results using LambdaTest?&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;
  &amp;lt;input type="text" id="debug" name="debug" value="Of-course!"&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;br&amp;gt;
  &amp;lt;input type="submit" value="Submit"&amp;gt;
&amp;lt;/form&amp;gt; &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;button type="button" onclick="alert('Page Source Example : LambdaTest!')"&amp;gt;Click Me!&amp;lt;/button&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Is An HTML Web Element?
&lt;/h2&gt;

&lt;p&gt;The easiest way to describe an HTML web element would be, “any HTML tag that constitutes the HTML page source code is a web Element.” It could be an HTML code block, an independent HTML tag like &amp;lt;/br&amp;gt;, a media object on the web page – image, audio, video, a JS function or even a JSON object wrapped within &amp;lt;script&amp;gt; &amp;lt;/script&amp;gt; tags.&lt;/p&gt;

&lt;p&gt;In the above example – &amp;lt;title&amp;gt; is an HTML web element, so is&lt;/p&gt;

&lt;p&gt;and the children of body tags are HTML web elements too i.e., &amp;lt;img&amp;gt;, &amp;lt;button&amp;gt; etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Get Page Source In Selenium WebDriver Using Python?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.lambdatest.com/blog/selenium-webdriver-tutorial-with-examples/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt; is a robust automation testing tool and provides automation test engineers with a diverse set of ready-to-use APIs. And to make Selenium WebDriver get page source, Selenium Python bindings provide us with a driver function called page_source to get the HTML source of the currently active URL in the browser.&lt;/p&gt;

&lt;p&gt;Alternatively, we can also use the “GET” function of Python’s request library to load the page source. Another way is to execute javascript using the driver function execute_script and make Selenium WebDriver get page source in Python. A not-recommended way of getting page source is using XPath in tandem with “view-source:” URL. Let’s explore examples for these four ways of how to get page source in Selenium WebDriver using Python –&lt;/p&gt;

&lt;p&gt;We’ll be using a sample small &lt;a href="https://pynishant.github.io/" rel="noopener noreferrer"&gt;web page&lt;/a&gt; hosted on GitHub for all four examples. This page was created to demonstrate &lt;a href="https://www.lambdatest.com/blog/drag-and-drop-in-selenium-python/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;drag and drop testing&lt;/a&gt; in Selenium Python using LambdaTest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get HTML Page source Using driver.page_source
&lt;/h3&gt;

&lt;p&gt;We’ll fetch “pynishant.github.io” in the ChromeDriver and save its content to a file named “page_source.html.” This filename could be anything of your choice. Next, we read the file’s content and print it on the terminal before closing the driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://pynishant.github.io/")
pageSource = driver.page_source
fileToWrite = open("page_source.html", "w")
fileToWrite.write(pageSource)
fileToWrite.close()
fileToRead = open("page_source.html", "r")
print(fileToRead.read())
fileToRead.close()
driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On successful execution of the above script, your terminal output will show the following page source.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage5-1-1024x576.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage5-1-1024x576.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Get HTML Page Source Using driver.execute_javascript
&lt;/h3&gt;

&lt;p&gt;In the previous example, we have to comment out (or replace) the “driver.page_source” line and add the following line. “driver.execute_script is a Selenium Python WebDriver API to execute JS in Selenium environment. Here, we execute a JS script that returns an HTML body element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pageSource = driver.page_source
pageSource = driver.execute_script("return document.body.innerHTML;")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output code looks like this-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage1-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage1-2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can observe, it only returns the innerHTML of the body element. Like the last output, we do not get the whole page source. To get the entire document, we execute “document.documentElement.outerHTML”. The execute_script line now looks like this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pageSource = driver.execute_script("return document.documentElement.outerHTML;")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us precisely the output we got using “driver.page_source.”&lt;/p&gt;

&lt;p&gt;Fetch Page Source Using Python’s Request Library In Selenium WebDriver. This method has nothing to do with &lt;a href="https://www.lambdatest.com/selenium?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt;, it’s a purely ‘Pythonic’ way to get a webpage source. Here, we use Python’s request library to make a get request to the URL and save the request’s response, i.e., page source to an HTML file and print on the terminal.&lt;/p&gt;

&lt;p&gt;Here is the script –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests
url = 'https://pynishant.github.io/'
pythonResponse = requests.get(url)
fileToWrite = open("py_source.html", "w")
fileToWrite.write(pythonResponse.text)
fileToWrite.close()
fileToRead = open("py_source.html", "r")
print(fileToRead.read())
fileToRead.close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method can be used to quickly store a webpage source code without loading the page in the Selenium-controlled browser. Similarly, we can use the urllib Python library to fetch the HTML page source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get HTML Page Source Using “view-source:” URL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is rarely required, but you can append the target URL with “view-source” and load it in the browser window to load the source code and save it in manual testing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage6-1-1024x546.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage6-1-1024x546.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Programmatically to take source code of &lt;a href="https://www.lambdatest.com/blog/python-selenium-screenshots/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;screenshots in Python Selenium&lt;/a&gt; (if required), you can load the page using –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.get("view-source:https://pynishant.github.io/")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get HTML Page Source In Selenium Python WebDriver Using XPath
&lt;/h3&gt;

&lt;p&gt;The fourth method to make Selenium WebDriver get a page source is to use XPath for saving it. Here, instead of page_source or executing JavaScript we identify the source element, i.e., &amp;lt;html&amp;gt; and extract it. Comment out the previous page source fetching logic and replace it with the following-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pageSource = driver.page_source
pageSource = driver.find_element_by_xpath("//*").get_attribute("outerHTML")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above script, we are using a driver method, “find_element_by_xpath,” to locate the web page’s HTML element. We enter the document using source node – &lt;code&gt;"//*"&lt;/code&gt; and get its “outer HTML,” which is the document itself. The output looks the same as we got earlier using driver.page_source.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Retrieve HTML Source Of WebElement In Selenium?
&lt;/h2&gt;

&lt;p&gt;To get the HTML source of a WebElement in Selenium WebDriver, we can use the get_attribute method of the &lt;a href="https://www.lambdatest.com/blog/selenium-webdriver-with-python/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium Python WebDriver&lt;/a&gt;. First, we grab the HTML WebElement using driver element locator methods like (find_element_by_xpath or find_element_by_css_selector). Next, we apply the get_attribute() method on this grabbed element to get it’s HTML source.&lt;/p&gt;

&lt;p&gt;Suppose, from pynishant.github.io, and we want to grab and print the source code of the div with id “div1”. The code for this looks like this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver

driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://pynishant.github.io/")
elementSource = driver.find_element_by_id("div1").get_attribute("outerHTML")
print(elementSource)
driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the output –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage2-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage2-1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, to get the children or innerHTML of a WebElement –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.find_element_by_id("some_id_or_selector").get_attribute("innerHTML")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is an alternative way of doing this and achieving same result –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elementSource = driver.find_element_by_id("id_selector_as_per_requirement")
driver.execute_script("return arguments[0].innerHTML;", elementSource)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How To Retrieve JSON Data From An HTML Page Source In Python Selenium WebDriver?
&lt;/h2&gt;

&lt;p&gt;Modern applications are built with multiple APIs at play. And often, these API dynamically change the content of HTML elements. JSON objects have emerged as an alternative to XML response types. So, it has become essential for a pro Selenium python tester to handle JSON objects, especially those embedded in &amp;lt;script&amp;gt; HTML tags. Python provides us with an in-built JSON library to experiment with JSON objects.&lt;/p&gt;

&lt;p&gt;To demonstrate with an example – we load “&lt;a href="https://www.cntraveller.in/%E2%80%9D" rel="noopener noreferrer"&gt;https://www.cntraveller.in/”&lt;/a&gt; in Selenium driver and look-out for SEO schema contained in &amp;lt;script type=”application/ld+json”&amp;gt; &amp;lt;/script&amp;gt; to verify that logo URL is included in the “JSON” schema. By the way, if you feel confused, this “SEO schema” is useful to get web pages ranked on google. It has nothing to do with code-logic or testing. We’re using it just for demonstration.&lt;/p&gt;

&lt;p&gt;We’ll be using LambdaTest for this demo-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver
import json
import re
username = "hustlewiz247"
accessToken = "1BtTGpkzkYeOKJiUdivkWxvmHQppbahpev3DpcSfV460bXq0GC"
gridUrl = "hub.lambdatest.com/wd/hub"
desired_cap = {
    'platform' : "win10",
    'browserName' : "chrome",
    'version' :  "71.0",
    "resolution": "1024x768",
    "name": "LambdaTest json object test ",
    "build": "LambdaTest json object test",
    "network": True,
    "video": True,
    "visual": True,
    "console": True,
}
url = "https://"+username+":"+accessToken+"@"+gridUrl
print("Initiating remote driver on platform: "+desired_cap["platform"]+" browser: "+desired_cap["browserName"]+" version: "+desired_cap["version"])
driver = webdriver.Remote(
    desired_capabilities=desired_cap,
    command_executor= url
)
# driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.cntraveller.in/")
jsonSource = driver.find_element_by_xpath("//script[contains(text(),'logo') and contains(@type, 'json')]").get_attribute('text')
jsonSource = re.sub(";","",jsonSource)
jsonSource = json.loads(jsonSource)

if "logo" in jsonSource:
    print("\n logoURL : " + str(jsonSource["logo"]))
else:
    print("JSON Schema has no logo url.")
try:
    if "telephone" in jsonSource:
        print(jsonSource["telephone"])
    else:
        print("No Telephone - here is the source code :\n")
        print(driver.find_element_by_xpath("//script[contains(text(),'logo') and contains(@type, 'json')]").get_attribute('outerHTML'))
except Exception as e:
    print(e)
driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output contains logoURL and webElement source –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage3.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage8-1-1024x546.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2Fimage8-1-1024x546.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Breakdown&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The following three lines import required libraries: Selenium WebDriver, Python’s JSON, and re library to handle JSON objects and use regular expressions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver
import json
import re
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCapture.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2021%2F01%2FCapture.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we configure our script for running it successfully on LambdaTest’s cloud, which is quite fast and smooth. It took me less than 30 seconds to get started (maybe because I had prior experience with the platform). But even if you are a first-timer, it would take less than 1 minute. &lt;a href="https://accounts.lambdatest.com/login" rel="noopener noreferrer"&gt;Register&lt;/a&gt; and login using Google and click on &lt;a href="https://accounts.lambdatest.com/detail/profile" rel="noopener noreferrer"&gt;Profile&lt;/a&gt; to copy your username and access token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;username = "your_username_on_lambdaTest"
accessToken = "your lambdaTest access token"
gridUrl = "hub.lambdatest.com/wd/hub"
desired_cap = {
    'platform' : "win10",
    'browserName' : "chrome",
    'version' :  "71.0",
    "resolution": "1024x768",
    "name": "LambdaTest json object test ",
    "build": "LambdaTest json object test",
    "network": True,
    "video": True,
    "visual": True,
    "console": True,
}
url = "https://"+username+":"+accessToken+"@"+gridUrl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We launch the driver in full-screen mode and load the cntraveller home page with the following line of code –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver = webdriver.Remote(
    desired_capabilities=desired_cap,
    command_executor= url
)
# driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.cntraveller.in/")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we locate JSON objects containing script using &lt;a href="https://www.lambdatest.com/blog/chrome-extensions-to-find-xpath-in-selenium/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;XPath locator&lt;/a&gt; and delete the unnecessary semicolons to load the string in JSON format properly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jsonSource = driver.find_element_by_xpath("//script[contains(text(),'logo') and contains(@type, 'json')]").get_attribute('text')
jsonSource = re.sub(";","",jsonSource)
jsonSource = json.loads(jsonSource)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then, we check if the logo URL is present. If present, we print it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if "logo" in jsonSource:
    print("\n logoURL : " + str(jsonSource["logo"]))
else:
    print("JSON Schema has no logo url.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, we check if the telephone detail is present. If not, we print the source code of the WebElement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try:
    if "telephone" in jsonSource:
        print(jsonSource["telephone"])
    else:
        print("No Telephone - here is the source code :\n")
        print(driver.find_element_by_xpath("//script[contains(text(),'logo') and contains(@type, 'json')]").get_attribute('outerHTML'))
except Exception as e:
    print(e)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, we quit the driver.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;driver.quit()&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Get Page Source As XML In Selenium WebDriver?
&lt;/h3&gt;

&lt;p&gt;If you’re loading an XML-rendered website, you may want to save the XML response. Here’s a working solution for making Selenium get XML page source –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;drive.execute_script(‘return document.getElementById(“webkit-xml-viewer-source-xml”).innerHTML’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You can use any of the above-demonstrated methods and leverage the agility &amp;amp; scalability of LambdaTest &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2032021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium Grid cloud&lt;/a&gt; to automate your test processes. It lets you execute your test cases on 2000+ browsers, operating systems, and their versions. Also, you can integrate the automation testing flow with modern CI/CD tools and adhere to the best continuous testing practices.&lt;/p&gt;

&lt;p&gt;So, start automating your day-to-day tasks and make your life easier with LambdaTest right away.&lt;/p&gt;

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

</description>
      <category>python</category>
      <category>selenium</category>
      <category>automation</category>
      <category>testing</category>
    </item>
    <item>
      <title>How To Switch Tabs In A Browser Using Selenium Python?</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Tue, 23 Feb 2021 09:00:01 +0000</pubDate>
      <link>https://forem.com/codepoetn/how-to-switch-tabs-in-a-browser-using-selenium-python-3hi5</link>
      <guid>https://forem.com/codepoetn/how-to-switch-tabs-in-a-browser-using-selenium-python-3hi5</guid>
      <description>&lt;p&gt;Selenium automation offers dexterous ways to perform day-to-day tasks most efficiently. From capturing screenshots to &lt;a href="https://www.lambdatest.com/blog/selenium-testing-pdf-files/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;testing PDF files&lt;/a&gt;, there’s no limit to what you can do with Selenium automation. Developers and testers are masters of drilling websites and finding loopholes. More often than not, this drill involves switching tabs multiple times a day. To reduce the manual effort that goes into doing so, we recommend using Python Selenium to switch tabs.&lt;/p&gt;

&lt;p&gt;In this article, we will help you master multiple ways to switch tabs in Selenium using Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Do We Need To Open Or Switch Tabs In Selenium Automation?
&lt;/h2&gt;

&lt;p&gt;Opening a new tab or switching between multiple tabs is one of the most basic functions performed by all of us every single day. Let us look into some scenarios when opening or switching tabs comes in handy during Selenium automation.&lt;/p&gt;

&lt;h3&gt;
  
  
  App Suits – Testing Features That Can Work Parallely
&lt;/h3&gt;

&lt;p&gt;The most obvious scenario is when your application is too big and has mini-applications within it. For example, if you have used Linkedin, you might have come across ‘Linkedin Learning’ &amp;amp; ‘Linkedin Sales Navigator’ as two sub-applications. Similarly, many other applications are composed of several other smaller constituent applications. For example, G-suite, Youtube (media player &amp;amp; creator studio), Hubspot, Azure &amp;amp; Amazon, etc., some of these, by default, open up in a new tab. For others, it makes sense to intentionally open a new application in a new tab. This is where Selenium automation testing comes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Ecommerce App Features
&lt;/h3&gt;

&lt;p&gt;Let’s take another example of e-commerce application testing. Suppose you are testing an e-commerce website and you want to add a product to the cart. Then, you want to check if it gets reflected on the cart page. Next, you want to add another product to the cart. And then you want to confirm if it is visible in the cart. Doing this in the same browser window and tab could be a tenacious &amp;amp; time-taking task, and that’s where Selenium automation comes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multimedia Uploading Functionality Testing
&lt;/h3&gt;

&lt;p&gt;Another common example could be of uploading multiple videos parallelly to a vlogging platform like Vimeo or Youtube. This is an ideal case for multi-browser, cross-tab testing.&lt;/p&gt;

&lt;p&gt;In short, automation testing involves switching tabs in the following scenarios –&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing parallel features of large applications. E.g., Zoho, G-suite, Office365, etc.&lt;/li&gt;
&lt;li&gt;Testing links that automatically open in a new tab. E.g. – eCommerce applications&lt;/li&gt;
&lt;li&gt;Parallel testing of independent applications if the need arises. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this Python Selenium switch tabs tutorial, we will be focusing on opening and switching between the tabs using Python &amp;amp; Selenium. We have dedicated articles for on-page testing operations like handling alerts, &lt;a href="https://www.lambdatest.com/blog/drag-and-drop-in-selenium-python/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;drag and drop objects&lt;/a&gt; using a mouse, or taking full-page screenshots. You may want to refer to those to dive deeper into Selenium automation use cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Create A New Tab In Selenium Python?
&lt;/h2&gt;

&lt;p&gt;In order to get started with Python Selenium switch tabs automation, your system needs to be equipped with the required tools. Here are all the prerequisites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have the latest Selenium-Python bindings, Python3, pip, virtualenv installed in your system&lt;/li&gt;
&lt;li&gt;You also have a path to the executable WebDriver of your browser choice in your system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If not, you can simply follow the instructions given in this &lt;a href="https://www.lambdatest.com/blog/selenium-with-python/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium 4 with Python&lt;/a&gt; blog to get started with Python Selenium switch tab automation. We can open new tabs in Selenium-Python by executing JavaScript as well as by using Selenium’s ActionChains class.&lt;/p&gt;

&lt;p&gt;Let’s see how this can be done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open New Tabs In Selenium By Executing JavaScript
&lt;/h3&gt;

&lt;p&gt;In the following code, replace “chrome_webdriver_executable_path” with the path to your chrome executable. Ideally, you should add it in your systems PATH variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Code 1-&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver
import time
driver = webdriver.Chrome(chrome_webdriver_executable_path)
driver.maximize_window()
driver.get("https://www.cntraveller.in/")
# to fire up a new tab using javascript and load google.com
driver.execute_script('''window.open("https://www.google.com", "_blank");''')
time.sleep(5)
driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;execute_script&lt;/em&gt; is a method provided by Selenium to execute JavaScript snippets inside the remotely controlled browser. It could be used to scroll the webpage, open a new window, fire-up an alert, and a lot more. &lt;em&gt;window.open&lt;/em&gt; is a DOM method to launch new tabs. It accepts URL, name, specs and replaces them as parameters. For our Selenium automation testing use-case, we’re only concerned with the URL &amp;amp; name. You may use specs to launch new tabs in different sizes and configurations.&lt;/p&gt;

&lt;p&gt;In “Sample Code 1”, if you want to open a blank tab in Selenium Python, then replace the line after the comment with the following code –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.execute_script('''window.open("", "_blank");''')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or another equivalent would be –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.execute_script('''window.open();''')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As “_blank” is the default value for the optional “name” parameter. “_parent”, “_self”, “_top” are some other values it can take to open the “url” in the parent frame, same window, or top frame, respectively.&lt;/p&gt;

&lt;p&gt;Open New Tabs In Selenium By Executing ActionChains Class&lt;/p&gt;

&lt;p&gt;The second way to launch a new tab in Selenium is to use the &lt;em&gt;key_up&lt;/em&gt; and &lt;em&gt;key_down&lt;/em&gt; method of Selenium’s ActionChains class and click on an HTML element with a link.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sample Code 2-&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(chrome_webdriver_executable_path)
driver.get('https://www.lambdatest.com/')
time.sleep(5)
# locates a link element on the loaded url using xpath
new_tab_link = driver.find_element_by_xpath('//a[contains(@class,"nav-link") and contains(@href,"selenium-automation")]')
time.sleep(5)
# instantiates ActionChains class of selenium webDriver
action = ActionChains(driver)
# clicks on located kink element with CONTROL button in pressed state using actionChains class. This opens the link in new tab 
action.key_down(Keys.CONTROL).click(new_tab_link).key_up(Keys.CONTROL).perform() 
time.sleep(3)
driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ActionChains class of selenium grid enables low-level interactions with the web application elements. Selenium automation testers often use it to move the mouse cursor, double-clicking an HTML element, dragging and dropping operations, and of course, to press keyboard keys. Key_down method of ActionChains imitates pressing a key passed as a parameter. The Key_up method releases the pressed key. Again, the key is passed as the parameter to the key_up method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open New Tabs In Selenium By Executing send_keys
&lt;/h3&gt;

&lt;p&gt;Another way to open new tabs in Selenium is by using send_keys to the “body” element. This is the syntax used-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't') 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You’ll find a lot of solutions on the web claiming – ‘This is identical to pressing Ctrl &amp;amp; ‘t’ key together on user-controlled browsers.’ or ‘This method fires up a new tab on the element in focus.’ If you have to open a link in a new tab, get the location of an element using XPath or CSS selectors and nest send_keys operation on it with &lt;strong&gt;Keys.CONTROL + ‘t’&lt;/strong&gt; as parameters. But sadly, this doesn’t work. We checked with the latest Selenium &amp;amp; Python version on the date of publishing this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Switch Tabs In Selenium Python?
&lt;/h2&gt;

&lt;p&gt;Switching tabs in selenium python is not that cumbersome. We can use the &lt;em&gt;current_window_handle&lt;/em&gt; &amp;amp; &lt;em&gt;window_handles&lt;/em&gt; method of &lt;a href="https://www.lambdatest.com/blog/selenium-webdriver-with-python/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt; to automate tab switching in the Selenium Grid using Python. Besides, we can also use ActionChains class to switch tabs in remotely controlled cross-browser automation testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Switch Tabs In Selenium Python By Executing switch_to_window, switch_to.window, current_window_handle &amp;amp; window_handles
&lt;/h3&gt;

&lt;p&gt;In this Selenium Python switch tab tutorial, we can get started by using several methods, including switch_to_window, switch_to.window, &lt;em&gt;current_window_handle&lt;/em&gt; &amp;amp; &lt;em&gt;window_handles&lt;/em&gt;. Before we jump off to the execution, you must note that the &lt;em&gt;switch_to_window&lt;/em&gt; method is now deprecated, and the switch_to.window method has replaced it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.common.action_chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ActionChains&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.common.keys&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Keys&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SwitchTab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# self.driver = webdriver.Firefox()
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Chrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chrome&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt; &lt;span class="n"&gt;executable&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_switch_tab&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&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;maximize_window&lt;/span&gt;&lt;span class="p"&gt;()&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.lambdatest.com/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# collects handle ID of current window
&lt;/span&gt;        &lt;span class="n"&gt;first_tab_handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;first_tab_handle : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="c1"&gt;# locates a link element on the loaded url using xpath
&lt;/span&gt;&lt;span class="n"&gt;new_tab_link&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_xpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;//a[contains(@class,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nav-link&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;) and contains(@href,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;selenium-automation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;)]&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ActionChains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# clicks on the located link element with CONTROL button in pressed state using actionChains class. This opens the link in a new tab.
&lt;/span&gt;
&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key_down&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CONTROL&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="n"&gt;new_tab_link&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;key_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CONTROL&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver.window_handles : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current window handle : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver focus is not switched to new tab opened using actionChains.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;window handle has changed. Driver switched focus to new tab.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# stores handle of tab opened using actionchains
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ctrl_click_tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver focus switched. New tab&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s handle id is - &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctrl_click_tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver focus is not shifted to new tab.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;execute_script&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="s"&gt;window.open(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_blank&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver.window_handles : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ctrl_click_tab&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Though, this tab seems to be an active window as it&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s highlighted but driver control still remains with the tab we last switched to.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ctrl_click_tab&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;js_tab_handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;js tab handle is -&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_tab_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;js_tab_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;js_tab_handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver focus shifted to js tab with handle id -&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.lambdatest.com/blog/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# shifts control or focus to the first window in window handles, it's not the last opened tab but 1st tab in order.
&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;switch_to_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.lambdatest.com/pricing&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_handles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.lambdatest.com/newsletter/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;first_tab_handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;current_window_handle : &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_window_handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver switched to first tab&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;driver switching failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&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;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Breakdown-&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let us break down the code for better clarity on Selenium Python switch tab automation. Here it goes-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import unittest
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.webdriver.common.keys import Keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we first import all the required dependent libraries. Python’s unittest module to write test cases in Python. WebDriver module from the python-selenium library to automate browser actions. And ActionChains class from Selenium WebDriver – to automate low-level interactions using mouse and keyboard interrupts. Python time module to implicitly or explicitly pause the execution or wait. Lastly, the Keys module from Selenium WebDriver to imitate keyboard button inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; def setUp(self):
        # self.driver = webdriver.Firefox()
        self.driver = webdriver.Chrome()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is to set up your testing browser environment. If you’re using a cloud automation testing platform like &lt;a href="https://www.lambdatest.com/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;LambdaTest&lt;/a&gt;, for that too, ideally, you have to configure settings in this function. Here we are using Chrome as our browser, but you may use any browser. The script works exactly the same with Firefox or Edge too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def test_switch_tab(self):
        driver = self.driver
        driver.maximize_window()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we define a function “test_switch_tab”. Ideally, if you’re using a unittest library, start this function name with “ &lt;strong&gt;test&lt;/strong&gt; ”. driver.maximize_window fires up Chrome instance in full-screen mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.get('https://www.lambdatest.com/')
time.sleep(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First line loads the LamdaTest homepage in our recently launched Chrome instance. &lt;em&gt;time.sleep(sec)&lt;/em&gt; pauses the program from executing the next lines for specified seconds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2FLamdaTest-homepage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2FLamdaTest-homepage.png" alt="LamdaTest homepage" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;first_tab_handle = driver.current_window_handle
print("first_tab_handle : "+str(first_tab_handle))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the &lt;em&gt;current_window_handle&lt;/em&gt; method of the driver to get &amp;amp; store the handle id for the active tab in a variable named &lt;em&gt;first_tab_handle&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new_tab_link = driver.find_element_by_xpath('//a[contains(@class,"nav-link") and contains(@href,"selenium-automation")]')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On LamdaTest’s homepage, we find a link to the selenium-automation page using XPath.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;action = ActionChains(driver)        action.key_down(Keys.CONTROL).click(new_tab_link).key_up(Keys.CONTROL).perform() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we instantiate ActionChains and perform key_down, click, and key_up chained operations to open the LambdaTest’s selenium-automation webpage in a new tab. We’ll skip explaining the next few self-explanatory code lines that demonstrate that &lt;strong&gt;the driver control remains with the first tab&lt;/strong&gt; by inquiring about the driver’s current_window_handle method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.switch_to.window(driver.window_handles[1])
ctrl_click_tab = driver.current_window_handle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we use the &lt;em&gt;switch_to.window&lt;/em&gt; method and pass it the handle id of the new tab launched using ActionChains class as an argument. This switched driver control to the tab with selenium-automation LamdaTest’s webpage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.execute_script('''window.open("", "_blank");''')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line launches a new tab. It does get highlighted, but the control is still with the selenium-automation tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for handle in driver.window_handles:
if (handle == first_tab_handle) or (handle == ctrl_click_tab):
        print(handle)
else:
        js_tab_handle = handle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above lines logically retrieve the handle id for JS triggered new tab and stores it in js_tab_handle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.switch_to.window(js_tab_handle)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line switches to the latest tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.switch_to_window(driver.window_handles[1])
driver.switch_to.window(driver.window_handles[-1])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also switch between tabs using &lt;em&gt;window_handles&lt;/em&gt; indexes, negative index counts in reverse order from the last tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fcoding-jag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fcoding-jag.png" alt="coding jag" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fselenium-python-tutorial.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fselenium-python-tutorial.png" alt="selenium python tutorial" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But it is a good idea to store ids in variables and switch tabs using variables just like the below line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.switch_to.window(first_tab_handle)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function gets automatically called after the test case gets executed and it shuts the driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def tearDown(self):
        self.driver.quit()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output-&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On successful execution of the above script, you shall see the following output –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fsuccessful-execution.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fsuccessful-execution.png" alt="successful execution" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Switch Between iFrames In Selenium Python?
&lt;/h3&gt;

&lt;p&gt;Switching between iFrames is similar to switching between tabs. The difference is in syntax. Here, we have to use &lt;strong&gt;switch_to.frame()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can switch between iFrames by locating the element using XPath or CSS Selectors, and we can also switch using the iFrame index.&lt;/p&gt;

&lt;p&gt;To transfer driver control back to default content, use &lt;strong&gt;switch_to.default_content()&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Switch Tabs Using Selenium Automation On LambdaTest Cloud
&lt;/h2&gt;

&lt;p&gt;Using a cloud-based platform is the best way to leverage Selenium automation and get the desired results seamlessly. You can perform Python Selenium switch tab automation on LamdaTest’s &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;cloud Selenium Grid&lt;/a&gt;to make the most of it.&lt;/p&gt;

&lt;p&gt;To do so, you can obtain the value for username, access token, and gridUrl upon registering with LambdaTest. You can register &lt;a href="https://accounts.lambdatest.com/register" rel="noopener noreferrer"&gt;here&lt;/a&gt; for free. Once you have the required information, you will need to declare your testing environment’s desired capabilities. LambdaTest’s Desired Capabilities Generator will provide you with the capabilities based on your choice of OS, browser &amp;amp; its version, resolution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution-&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def setUp(self):
        username = "YOUR_LAMBDATEST_USERNAME"
        accessToken = "YOUR_LAMBDATEST_ACCESS_TOKEN"
        gridUrl = "hub.lambdatest.com/wd/hub"
        desired_cap = {
            'platform' : "win10",
            'browserName' : "chrome",
            'version' :  "67.0",
            "resolution": "1024x768",
            "name": "LambdaTest selenium automation switch tabs using python",
            "build": "LambdaTest selenium python switch tabs",
            "network": True,
            "video": True,
            "visual": True,
            "console": True,
        }
        url = "https://"+username+":"+accessToken+"@"+gridUrl 
        print("Initiating remote driver on platform: "+desired_cap["platform"]+" browser: "+desired_cap["browserName"]+" version: "+desired_cap["version"])
        self.driver = webdriver.Remote(
            desired_capabilities=desired_cap,
            command_executor= url
        )
        # self.driver = webdriver.Firefox()
        # self.driver = webdriver.Chrome()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the only function that needs to change when executing your script in the LamdaTest’s cloud Selenium Grid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cloud automation testing engineers get the flexibility and agility to uninhibitedly unleash their functional, acceptance, white-box, black-box, and regression testing drills on target web &amp;amp; mobile applications. While they do all this, switching between tabs might take up a lot of time. If you want to take your automation skills to the next level, start automating with Python &lt;a href="https://lambdatest.com/selenium?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-23022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt; switch tab automation and save a lot of manual effort.&lt;/p&gt;

&lt;p&gt;Additionally, we recommend leveraging LambdaTest’s cloud-based platform is easy and cost-effective. With 2000+ operating systems &amp;amp; browsers to offer, there’s so much you can do with LambdaTest automation.&lt;/p&gt;

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

</description>
      <category>python</category>
      <category>selenium</category>
      <category>automation</category>
    </item>
    <item>
      <title>12 Common Web Design Mistakes To Avoid in 2021</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Tue, 02 Feb 2021 07:10:18 +0000</pubDate>
      <link>https://forem.com/codepoetn/12-common-web-design-mistakes-to-avoid-in-2021-4l7p</link>
      <guid>https://forem.com/codepoetn/12-common-web-design-mistakes-to-avoid-in-2021-4l7p</guid>
      <description>&lt;p&gt;It is no secret that the website is the backbone of every business. If you want your business to be successful in this COVID-19 era, you’ve got to have a well-designed website. As, due to social distancing, more and more potential customers are searching for information via the company’s website.&lt;/p&gt;

&lt;p&gt;A well-designed website can help you grow your business as a flawless design creates a great impression on your potential customers inducing them to take the desired action. Common web design mistakes, however, can quickly derail even your best efforts. And while you hear a lot about what to do when designing your website. But do you know what not to do?&lt;/p&gt;

&lt;p&gt;Well, to give you an edge, we have outlined 12 common website design mistakes that hurt many businesses. Avoid them while designing your website, and you should have more success in converting visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Web Design And Why It Is Important?
&lt;/h2&gt;

&lt;p&gt;Before we cover these common web design mistakes in detail, it is crucial to understand what web design is all about. Web design is a process of iteratively strategizing, conceptualizing, and delivering information and overall business functionality in an aesthetically appealing layout.&lt;/p&gt;

&lt;p&gt;Visual components of web design encompass the text content, images, videos, colors, fonts, different elements and shapes like buttons, forms, icons, the spacing between these elements, and the overall layout itself.&lt;/p&gt;

&lt;p&gt;Design functionality comprises website speed, navigation, animation, user experience, user interaction, overall site’s tech architecture, SEO, cross-browser, cross-platform, cross-device design consistency, and responsiveness.&lt;/p&gt;

&lt;p&gt;Now that we’ve covered web design and why it’s so important, it’s time to understand the common web design mistakes designers and developers must avoid in 2021.&lt;/p&gt;

&lt;h2&gt;
  
  
  12 Common Web Design Mistakes
&lt;/h2&gt;

&lt;p&gt;We all know to err is human, but to avoid mistakes in the first place is divine. With that in mind given below are 12 common web design mistakes that you must avoid.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Not Opting For Design-Thinking Approach Before Implementation
&lt;/h3&gt;

&lt;p&gt;One of the most common web design mistakes that most designers make is that they don’t realize the importance of design-thinking and drawing the layout on-paper. Designers often tend to “assume things” about users rather than carry out extensive “user research” to understand user needs. But this is not the right way to go about web design.&lt;/p&gt;

&lt;p&gt;Understanding the design thinking approach is the key to designing addictive experiences for users. Not sure what design-thinking is – well, it is a process that understands and identifies customer needs and motivations. It’s a mindset to empathize with the customers, detail their problems, and build solutions to solve them.&lt;/p&gt;

&lt;p&gt;The design thinking approach enables designers to identify goals, project scope, build business features, understand user requirements, technological capabilities, solution feasibility, and effectiveness. All this helps designers gather data-points to devise the right sitemaps and wireframes before hopping on to some designing software.&lt;/p&gt;

&lt;p&gt;Remember – If you don’t understand your customers, you won’t be able to design good websites for them. So, be empathetic, and do user research to understand what your customers care about.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Not Prioritising Grids &amp;amp; Columns
&lt;/h3&gt;

&lt;p&gt;We all know that the web design world is changing at a remarkable speed, and you need to change with it too. But some of the designers are still confined to developing designs the old way, i.e., organizing content by only using flexbox, float, breakpoints, etc., and overlook the importance of CSS grids and guides in developing responsive well-architectured websites designs. On the other hand, many junior developers have this misconception that flexbox and floats are dead. It’s a misconception. CSS grids, flexbox, floats, and breakpoints are all important from a web designer’s perspective, and using it in the right way can help avoid all grid &amp;amp; column related web design mistakes.&lt;/p&gt;

&lt;p&gt;Using CSS technologies, designers can deliver a seamless user-experience where content gets automatically segmented and aligned using rows and columns. Grid-template-columns, minmax, autofit properties of CSS eliminates the need to use media queries breakpoints but using grid-template-areas does need to use breakpoints.&lt;/p&gt;

&lt;p&gt;One of the CSS grid-related web design mistakes most designers tend to make is getting confused with CSS numbers. While designing for CSS frameworks like bootstrap, we count the number of columns in a row, usually 12, but in the grid system, we count lines or stacks. In the grid system, moving from lines 1 to 7 is akin to spanning 6 columns.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2F12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2F12.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Not Strategizing Hierarchical Aesthetics
&lt;/h3&gt;

&lt;p&gt;Another web design mistake that most designers need to avoid is not strategizing the visual hierarchy of content, including CTAs. Well devised user journeys can be efficiently implemented by designing efficient visual hierarchies. This can be achieved by using appealing words, colors, images, and small animations. Spacing between these elements and their size can also be very crucial in driving user engagement. Getting this wrong means less user interaction and can hurt your business profitability.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Not Prioritising Intuitive Navigation &amp;amp; Accessibility
&lt;/h3&gt;

&lt;p&gt;Skipping the essential step of brainstorming, sitemap, and wireframing is the basis of several web design mistakes. One of the prominent ones being the poorly configured menu and navigation layout. An improper navigational structure can drive away your website visitors as it’s a pain to scroll through randomly structured websites. Suppose you’re designing a website with loads of pages, then it makes sense to group them into categories and arrange these categories hierarchically to enable users to navigate the website intuitively.&lt;/p&gt;

&lt;p&gt;Moreover, navigation is not the same for every device. Though there are different ways to work with navigation, you need to choose the right strategy. For example, while working with mobiles, you can choose a hamburger menu strategy, as it works great for navigation on smaller screens. If you wish to compare the navigation of your website on mobile and tablets, you can use the &lt;a href="https://www.lambdatest.com/blog/introducing-lt-browser-for-mobile-view-debugging?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;LT Browser – A Responsive Design Checker Tool&lt;/a&gt; to do so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2FLT-Browser-responsive-web-design-checker.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2FLT-Browser-responsive-web-design-checker.png" alt="responsive-design-checker" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other than navigation, there are some other aspects to boost website accessibility. Research says there are 300+ Mn people with color blindness. But most designers overlook this aspect while designing websites and user journeys. There are millions of people with visual and hearing disabilities. Not taking these users in your design-thinking approach could be one of the major yet common website design mistakes.&lt;/p&gt;

&lt;p&gt;Text size, color contrasts, page titles, image alternate text, keyboard accessibility, moving and blinking contents like carousels, ads, autoplaying videos, scrolling news feeds, and tickers are crucial components of a website from the accessibility point of view. A person battling hypermetropia might want to zoom the content on small devices. A person with visual impairment may prefer speech to consume content rather than text. A user with attention-deficit may want to pause carousels and so on. A good web design takes all this into the picture to enhance website accessibility. Doing it wrong can lead to a bad user experience and hurt your business. Given below is an example of an intuitive web design:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fintuitive-web-design.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fintuitive-web-design.png" alt="intuitive web design" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above example of Amazon’s website shows how they have used the search functionality in the best way one can imagine. An easy-to-use site search functionality avoids the need to have labeling menu items built-in for a diverse set of users.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Not Adhering To Security-First, Responsive Design Approach
&lt;/h3&gt;

&lt;p&gt;Though website security is much of a technical architecture-dependent aspect but to an extent, it is also related to website design and user journeys. How designers depict the user journeys greatly influences how developers implement the designs. If website security is prioritized right from the design stage, many security loopholes can be avoided. For example, putting the business-critical data behind authentication and payment walls.&lt;/p&gt;

&lt;p&gt;Read our blog if you are curious about finding the influence of &lt;a href="https://www.lambdatest.com/blog/does-microservices-architecture-influence-security-testing/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Microservice architecture in Security testing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Besides security, the design must be responsive and consistent across browsers and devices to offer an omnichannel experience. One of the big web design mistakes in website development is designing different user journeys and roadmaps for different platforms and devices. The priority should be to maintain as much consistency across devices as possible. It would be better if you can check the responsiveness before making it live. Tools like &lt;a href="https://www.lambdatest.com/lt-browser?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;LTBrowser&lt;/a&gt; from LambdaTest allows you to design responsive websites without any hassle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fperformance-report-LT-Browser.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fperformance-report-LT-Browser.gif" alt="performance report LT Browser" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Cluttering Up The Web Design With Too Much Content
&lt;/h3&gt;

&lt;p&gt;Too little information and you run the risk of not delivering the solution your user is looking for. Too much information and you may end up building a solution that is hard to understand, consume, or access. In their sheer desperation, designers can overwhelm the visitors with resources and end-up delivering a highly cluttered website. Though it is successful because it’s highly popular since the early days. And maybe to maintain consistency for its users, they still haven’t changed the website design. But one should not make the same mistake.&lt;/p&gt;

&lt;p&gt;One of the common web design mistakes to avoid is not building scalable designs from the very beginning. This is the core reason behind so many businesses revamping their website design. Unstructured, un-templated website designs are a growth bottleneck because, after a few hundred pages, it becomes erroneously difficult to maintain, develop, and scale these websites. To avoid these design scalability issues, the design approach should embrace a “divide and conquer” strategy.&lt;/p&gt;

&lt;p&gt;Divide the overall website interface into different web pages like product listing, product information, user profiles, user interaction, etc. Next, divide each webpage interface constituents into reusable blocks and components. Each of these components should focus on delivering one functionality. For example, carousels, short user profiles, product descriptions, reviews, etc. Next, use these components to build the overall website. This approach ensures faster development and scalability of the webpages. Given below is an example of a cluttered and bad website design:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fweb-design-mistakes.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F12%2Fweb-design-mistakes.jpg" alt="Web Design Mistakes" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Not Having A Clear CTA
&lt;/h3&gt;

&lt;p&gt;Not having a clear CTA is another common web design mistake. Websites are like marketing and sales funnel or pipeline. Your website visitor traverses within that funnel to go from the prospects’ stage to the converted clients’ stage. Not giving a clear “call to action” at the appropriate places may lead to not converting many hot prospects. Overdoing CTA may also lead to irritating prospects. You can learn about the 18 most effective &lt;a href="https://www.lambdatest.com/blog/18-cta-design-tips-to-boost-your-websites-conversion-rate/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;CTA design tips&lt;/a&gt; to boost your website’s conversion rate.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Poorly Designed Or Irrelevant Images
&lt;/h3&gt;

&lt;p&gt;We all know that images and graphics are a critical part of web design. When done well, images can clearly convey the message to the visitor. Done wrong, they can confuse the reader. Many businesses are still not paying attention to their images and are using low-quality and irrelevant images. Don’t make this mistake, as low-quality images will muck up your website and turn off your visitors, which will hurt your conversions. Similarly, irrelevant images will only confuse your visitors, inducing them not to take the desired action. That being said, you should also not clutter your website with too many images as they can take away the eyes from CTA, leading to a loss in conversions.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Not Paying Attention To 404 Page Design Can Hurt SEO
&lt;/h3&gt;

&lt;p&gt;Web design is not just limited to developing layouts and user journeys. Wikipedia definition expands web design to incorporate content and search engine optimization (SEO). From the SEO point-of-view, multiple common website design mistakes can be easily avoided.&lt;/p&gt;

&lt;p&gt;The first SEO-critical web design mistake is not to have a dedicated custom 404-page template. You can have a custom 404 page for your domain to present users with something relevant, or you may use 302 or 301 redirects to link to some other page on the web. Broken links on a website harm a business reputation. Users feel as if the website is a scam, and the product/service won’t be of standard. Using 302 or 301 redirects, these broken links could be easily handled. For an external website with broken links, you’ve to test, identify, and replace such links continuously.&lt;/p&gt;

&lt;p&gt;Secondly, SEO-specific and common website design mistakes include not using title &amp;amp; heading tags. Using descriptive page text won’t be as impactful as describing it in the title. Similarly, using larger fonts won’t be as impactful for SEO as using h1, h2 tags.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Multimedia Related Web Design Mistakes
&lt;/h3&gt;

&lt;p&gt;We already highlighted how irritating autoplay videos are, especially with sound. Additionally, it makes websites pretty slow to load. It’s often better to not autoplay videos and wait for some sort of user activity to trigger playing such videos. For example, the user scrolls to a section on your page containing the video.&lt;/p&gt;

&lt;p&gt;We also underlined how fast carousels could be a turn off too. Other than these, there are a few more multimedia related web design mistakes that should be avoided.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, a massive web design mistake is not to optimize your website images. Big size images make websites slow to load. If your website loads slow, it can hurt your conversions terribly. Did you know &lt;a href="https://www.websitebuilderexpert.com/building-websites/website-load-time-statistics/" rel="noopener noreferrer"&gt;1 in 4 visitors&lt;/a&gt; would abandon a website that takes more than 4 seconds to load? Even search engines don’t like such websites. So, as a designer, it is preferable to use clear and optimized images. As a developer, the attempt should be to lazy load these images. Lazy loading of images makes websites faster to load.&lt;/li&gt;
&lt;li&gt;Second, avoid using cheap free stock images. Everyone has used them; everyone knows when you use one! It creates a cheap impression. So, if the free-stock image is not exactly spot-on, avoid using it.&lt;/li&gt;
&lt;li&gt;Third, use contextual icons esp, favicons. We understand it’s an obvious thing, but a surprising number of designers don’t do this even in 2020. This helps in delivering the right message and boosts branding too.&lt;/li&gt;
&lt;li&gt;Fourth, do not use several font styles on the same web page. Not maintaining the font’s style consistency across the webpage is another common web design mistake.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  11. Not Designing Multilingual Voice Enabled Website Designs
&lt;/h3&gt;

&lt;p&gt;Today it is possible to build websites in multiple languages and even add voice interface based functionalities. But not many designers and website owners are utilizing these web capabilities. If a business has customers in different countries, then to appeal better to target customers, websites can be developed in the native language. To boost accessibility, a voice-based interface can be added to the website. A big chunk of the google searches on phones is voice-based. Users are using voice technology to book cabs, hotels, etc. It would be a mistake not to count the voice and multilingual approach in the overall website design plan.&lt;/p&gt;

&lt;p&gt;Keeping in mind the customers from different countries, you might be interested to know how your website may appear and work differently through different countries and continents and how to perform &lt;a href="https://www.lambdatest.com/blog/geolocation-testing-through-vpn-on-lambdatest/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Geolocation cross browser testing through VPN on LambdaTest&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  12. Not Harnessing Analytics Or Testing To Ensure Cross Browser Compatibility
&lt;/h3&gt;

&lt;p&gt;The design, like content, is a creative work that can be improved iteratively. Using sophisticated analytics tools, your website analytics administrator can give you data on how users navigate your website. Also, analytics, testing can help you discover broken links. Based on the analytics input, you can find out the flaws in the user journey. You can identify what’s working and what needs improvements, which CTAs are getting clicked, which needs to be upgraded.&lt;/p&gt;

&lt;p&gt;After completing the development phase successfully, keeping in mind all the website design problems and web design mistakes to avoid, we can proceed to the testing phase. Testing a website is an indispensable step as the world is filled with devices that are either different physically or from the inside. Cross browser testing, usability testing, and A/B testing are just a few to name as different goals demand different testing types.&lt;/p&gt;

&lt;p&gt;One of the most common website design mistakes that developers tend to commit is assuming that a redesigned website is perfect and not performing &lt;a href="https://www.lambdatest.com/feature?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-2022021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;browser compatibility testing&lt;/a&gt; as rigorously as they should. They feel that since the redesigned website has similar functionalities to the previous one, rigorous rechecking functionalities are meaningless. This, albeit, is not a good approach and is an unforgivable blunder in the redesigning part. With this mentality, a lot of things can go wrong, such as cross browser compatibility. Therefore, always test your website with equal commitment to optimize and make it bug-free for your audiences, thereby avoiding all related website design problems.&lt;/p&gt;

&lt;p&gt;LambdaTest can help you identify and overcome such mistakes by allowing you to perform cross browser testing of a website on 2000+ browsers and their versions, with the help of VMs hosted on their cloud servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Over To You
&lt;/h2&gt;

&lt;p&gt;A website could be your business’s most important asset, so you need to make it flawless to create a great first impression. But to do that, you need to avoid these web design mistakes.&lt;/p&gt;

&lt;p&gt;Don’t worry. These common website design mistakes are fairly easy to avoid as well as fix. Identifying them is the hardest step. But now that you know these mistakes, you can easily avoid or fix them moving forward.&lt;/p&gt;

&lt;p&gt;So, are you making any of these web design mistakes? Is there any other common website design mistake that you want to add to this list? Please, chime in the comment section below!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>responsive</category>
    </item>
    <item>
      <title>How To Drag And Drop In Selenium With Python?</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Thu, 21 Jan 2021 10:12:44 +0000</pubDate>
      <link>https://forem.com/codepoetn/how-to-drag-and-drop-in-selenium-with-python-1jnh</link>
      <guid>https://forem.com/codepoetn/how-to-drag-and-drop-in-selenium-with-python-1jnh</guid>
      <description>&lt;p&gt;Drag and Drop- one of the most beloved and commonly used gestures in the world of GUIs. Many actions are associated with drag and drop, including moving an object from one location to another to creating associations between them. Be it an image editing tool like Canva, a cloud-storage manager like Google Drive, or project planning &amp;amp; collaboration tools like Trello, Asana, Jira, drag, and drop functionality can be found everywhere.&lt;/p&gt;

&lt;p&gt;You might have used it for positioning multimedia objects like text, images, video clips, etc., moving files to directories, and moving HTML elements/buttons within tables or between different pixel locations. Additionally, modern websites have started implementing sophisticated drag and drop captcha or bot detection. In all such applications and services, web developers and QA engineers face challenges in writing test cases for performing drag and drop in &lt;a href="https://www.lambdatest.com/blog/selenium-python-pytest-testing-tutorial/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-21012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium Python&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article, we’ll look in detail at how to perform drag and drop in Selenium with Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Drag And Drop Operation In HTML?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FOperation-In-HTML.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FOperation-In-HTML.gif" alt="Operation In HTML" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drag and drop is natively a graphical user interface (GUI) based software feature. The world wide web (w3) working draft HTML specifications, which declares standard practices for the modern web to promote interoperability and conformance, includes support for drag and drop operations for progressive web applications in desktop and mobile browser windows.&lt;/p&gt;

&lt;p&gt;Basically, drag and drop is a chain of pointing device (mouse) events/gestures on GUI software applications (including web browsers). It involves –&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving the cursor/pointer to where the object is located.&lt;/li&gt;
&lt;li&gt;Clicking or pressing the pointer device (mouse) to grab the object of interest.&lt;/li&gt;
&lt;li&gt;Moving the pointer device in a pressed state to the desired location.&lt;/li&gt;
&lt;li&gt;Releasing the pointer device button to drop the grabbed object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drag and drop are sometimes also referred to as “click and drag,” “click and drop” and on touch-screen applications, its equivalent would be “long press, drag, and drop.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview Of Python-Selenium WebDriver
&lt;/h2&gt;

&lt;p&gt;Selenium Python WebDriver bindings is a simple open-source API based interface to automate web browsers like Firefox, Chrome, Edge, Safari, Opera, and several others. Using Python Selenium bindings, software testing engineers write automated functional or acceptance test cases and have access to all the features of &lt;a href="https://www.lambdatest.com/blog/selenium-webdriver-tutorial-with-examples/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-21012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is an overview of command line commands for Windows to install and start Selenium with Python:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install virtualenv&lt;/code&gt; (only if virtualenv is not globally installed on your system)&lt;br&gt;&lt;br&gt;
&lt;code&gt;mkdir your_test_directory_name&lt;/code&gt; (create a directory for testing scripts if you don’t have one already. If you have a testing directory, skip this step.)&lt;br&gt;&lt;br&gt;
&lt;code&gt;cd your_test_directory_name&lt;/code&gt; (move into your test directory)&lt;br&gt;&lt;br&gt;
&lt;code&gt;virtualenv venv&lt;/code&gt; (create a virtual environment for your directory)&lt;br&gt;&lt;br&gt;
&lt;code&gt;venv/scripts/activate&lt;/code&gt; (activate the virtualenv)&lt;br&gt;&lt;br&gt;
&lt;code&gt;pip install selenium&lt;/code&gt; (install selenium within the activated virtualenv)&lt;/p&gt;

&lt;p&gt;To download browser web drivers, hit the respective links for &lt;a href="https://sites.google.com/a/chromium.org/chromedriver/downloads" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt;, &lt;a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/" rel="noopener noreferrer"&gt;Edge&lt;/a&gt;, &lt;a href="https://github.com/mozilla/geckodriver/releases" rel="noopener noreferrer"&gt;Firefox&lt;/a&gt;, Safari. While developing scripts on the local system, to invoke these WebDrivers using Selenium-Python, you need to ensure that the respective web drivers are in the same directory or you have added PATH environment variables to their respective executables (.exe files).&lt;/p&gt;

&lt;p&gt;Now, you’re all set to write and run your test scripts to drag and drop in Selenium Python WebDriver bindings inside a web browser.&lt;/p&gt;
&lt;h2&gt;
  
  
  How To Implement Drag And Drop In Selenium-Python?
&lt;/h2&gt;

&lt;p&gt;We can implement drag and drop in Selenium Python with the help of ActionChains class. Selenium WebDriver APIs expose &lt;strong&gt;ActionChains&lt;/strong&gt; class to automate low level user interactions with the website using a mouse, keyboard, etc. We shall use the same class to imitate and write test cases for drag and drop interaction using Selenium with Python.&lt;/p&gt;
&lt;h3&gt;
  
  
  What Is ActionChains Class?
&lt;/h3&gt;

&lt;p&gt;Often for writing automated test cases, testing engineers have to perform mouse and keyboard operations; the ActionChains class comprises intuitive methods to perform these interactions. For instance, using ActionChains, we can implement clicking on HTML elements or double click on an object. We can even send keyboard keys, pause inputs, move cursor to a specific location, move mouse by the desired offset and obviously, we can perform drag and drop in Selenium Python.&lt;/p&gt;

&lt;p&gt;The methods exposed using ActionChains –&lt;/p&gt;

&lt;p&gt;click(), click_and_hold(), context_click(), double_click(), &lt;strong&gt;drag_and_drop(source, target), drag_and_drop_by_offset(source, x_offset, y_offset)&lt;/strong&gt;, key_down(value), key_up(value), move_by_offset(x_offset, y_offset), move_to_element(target_element), move_to_element_with_offset(target_element, x_offset, y_offset), pause(seconds), perform(), release(), reset_actions(), send_keys(keys_to_send), send_keys_to_element(element, keys_to_send)&lt;/p&gt;
&lt;h3&gt;
  
  
  Performing Drag And Drop Using ActionChains Class
&lt;/h3&gt;

&lt;p&gt;In this article, we detail the drag_and_drop( &lt;strong&gt;source, target&lt;/strong&gt; ) and &lt;strong&gt;drag_and_drop_by_offset(source, x_offset, y_offset)&lt;/strong&gt; functions of ActionChains class. We will cover all other ActionChains methods in another article.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;drag_and_drop(source, target)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This method accepts two arguments: source &amp;amp; target. As the name goes, drag and drop ActionChains involves first locating the “source” element, then dragging it to the target location and dropping it. To select a source and target element, you may use &lt;a href="https://www.lambdatest.com/blog/selectorshub-the-next-gen-xpath-css-selectors-tool/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-21012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;XPath or CSS Selectors&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;drag_and_drop_by_offset(source, x_offset, y_offset)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This method requires three arguments: source, x_offset, and y_offset. drag_and_drop_by_offset is an alternative to using drag_and_drop. It involves identifying the source element and x,y offsets of the target location. After that, it drops the selected source to the desired offset location.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Performing chained click_and_hold(element), move_by_offset(xOffset, yOffset), pause(sec) and release() methods&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;click_and_hold(argument) method simulates the “left mouse button press and hold” operation. move_by_offset(x,y) resembles moving the cursor by specified x and y pixels on respective axes. Pause(sec) function pauses the action for a declared number of seconds. Release() method frees the remotely pressed mouse button.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Performing chained click_and_hold(element), move_to_element(target), pause(sec), move_by_offset(xOffset, yOffset) and release() methods&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;move_to_element(arg) is similar to moving the cursor to the specified argument. In our case, we’ll use these operations for drag and drop in Selenium Python by simulating click using click_and_hold, then dragging by using move_to_element or move_by_offset or combo, and by finally releasing, i.e., dropping the selected element.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demonstration- Drag And Drop Using Python Selenium WebDriver
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FPython-Selenium-WebDriver.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FPython-Selenium-WebDriver.png" alt="Python Selenium WebDriver" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we’ll use “&lt;a href="https://jqueryui.com/droppable/%E2%80%9D" rel="noopener noreferrer"&gt;https://jqueryui.com/droppable/”&lt;/a&gt; and “&lt;a href="https://jqueryui.com/draggable/" rel="noopener noreferrer"&gt;https://jqueryui.com/draggable/&lt;/a&gt;” page to demonstrate the automation of drag and drop testing using Selenium – Python WebDriver bindings.&lt;/p&gt;
&lt;h3&gt;
  
  
  Demo for drag_and_drop(source, target) and drag_and_drop_by(source, xoffset, yoffset)
&lt;/h3&gt;

&lt;p&gt;For demonstrating “drag_and_drop_by_offset,” we will use the “draggable” link, and to demonstrate “drag_and_drop,” we shall use the “droppable“ link. In the draggable link, we have a box that can be freely moved across its canvas. We have two boxes in the “droppable” link; we will move box one over box2.&lt;/p&gt;

&lt;p&gt;A sample automation test script using Selenium with Python for dragging and dropping would look like this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;selenium.webdriver.common.action_chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ActionChains&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DragTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;webdriver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Firefox&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_drag_drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&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;maximize_window&lt;/span&gt;&lt;span class="p"&gt;()&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://jqueryui.com/draggable/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;source1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;draggable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ActionChains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drag_and_drop_by_offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://jqueryui.com/droppable/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;source1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;draggable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;target1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;droppable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;actions2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ActionChains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;actions2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drag_and_drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dropped!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tearDown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&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;quit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Walkthrough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s understand the script in detail –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import unittest
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import Python’s inbuilt testing library “unittest” to write standard test cases. Next, we import “Python Selenium WebDriver bindings” to remotely control browser activity and automate interactions. We also explicitly import the “ActionChains” class from the Selenium WebDriver package, and lastly, we import “time” to invoke explicit pauses so that you can visualize the interactions. In production, you won’t need sleep time, at least not for this use-case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class DragTest(unittest.TestCase):
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a class DragTest, which extends on or, say, inherits the TestCase class of unittest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def setUp(self): 
    self.driver = webdriver.Firefox()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Python program or application can have multiple test cases, and they may have a repetitive set-up code. For example, configurations of intended browsers to test the application on. We can factor out such repetitive set-up codes by implementing them in setup() function. This function gets automatically invoked by the testing framework with every run of a new test. In our case, we are launching &lt;a href="https://www.lambdatest.com/blog/selenium-firefox-driver-tutorial/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-21012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Selenium FirefoxDriver&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def test_drag_drop(self):
    driver = self.driver
    driver.maximize_window()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we write the core logic of our automated test for drag and drop interactions. Here, we are creating a short reference variable “driver” for “self.driver”. And we invoke maximize_window() method of our driver to launch the browser in full-screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.get('https://jqueryui.com/draggable/') 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;get(url) method of the WebDriver, loads the specified url in the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.switch_to.frame(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For your information, jqueryui[dot]com is using iframes to demo drag-and-drop functionality. WebDriver’s get_element_by_* (ID, name, css) method will identify the element after switching to our target iframe. Here we are switching to the target iframe by using the index parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source1 = driver.find_element_by_id('draggable')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we find the draggable element (inspecting the url, you’ll find the element has an id equal to “draggable.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;action = ActionChains(driver)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an instance of ActionChains.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;action.drag_and_drop_by_offset(source1, 100, 100).perform()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we use drag_and_drop_by_offset(source, xOffset, yOffset) method to move the draggable element by 100 pixels on the x-axis and 100 on y-axis.&lt;br&gt;&lt;br&gt;
You may create multiple lines for dragging the draggable element based on test requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;time.sleep(5)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is to pause the script execution for 5 seconds, just to visualize things. In headless browsers, we can ignore this line for faster drag and drop testing using Python Selenium WebDriver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   driver.get('https://jqueryui.com/droppable/')
        driver.switch_to.frame(0)
        source1 = driver.find_element_by_id('draggable')
        target1 = driver.find_element_by_id('droppable')
        actions2 = ActionChains(driver)
        actions2.drag_and_drop(source1, target1).perform()
        time.sleep(5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, for the drag_and_drop(source, target) method, we first load the required url in the browser, switch to the target iframe using the index, identify the source element, i.e., the element which needs to be dragged. And the target element, i.e., the target location where the draggable element needs to be dropped. Lastly, we create a stance of ActionChains and invoke drag_and_drop(src, dest) method. perform() function carries out all the chained interactions.&lt;/p&gt;

&lt;p&gt;If the test case executes successfully, you shall see this output on your computer screen –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fimage1-1-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fimage1-1-1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  click_and_hold(element), move_to_element(target), pause(sec), move_by_offset(xOffset, yOffset), release()
&lt;/h3&gt;

&lt;p&gt;To demonstrate drag and drop in Selenium Python using the above methods, we need to write another test with modifications in the test_drag_drop(self) function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_drag_drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;driver&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;maximize_window&lt;/span&gt;&lt;span class="p"&gt;()&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://jqueryui.com/draggable/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;source1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;draggable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ActionChains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click_and_hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move_by_offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move_by_offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dragging &amp;amp; dropping test case successful&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://jqueryui.com/droppable/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;switch_to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;source1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;draggable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;target1&lt;/span&gt; &lt;span class="o"&gt;=&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;find_element_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;droppable&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;actions2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ActionChains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;actions2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click_and_hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move_to_element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move_by_offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dragging &amp;amp; dropping test case successful&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Dropped!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Walkthrough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s understand how it differs from the earlier code –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;action.click_and_hold(source1).move_by_offset(150, 100).pause(2).move_by_offset(-10, -10).release().perform()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here instead of using drag_and_drop_by_offset(), we simulate the same set of interactions using chained methods. We have first identified the draggable element on the jqueryUI page, remotely clicked on it, moved it by 150 pixels on the x-axis and 100 on the y, paused for two seconds, and again moved the clicked element by 10 pixels in the negative x,y direction. Finally, dropped the element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;actions2.click_and_hold(source1).move_to_element(target1).pause(2).move_by_offset(20, 20).release().perform()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to the above one, we execute the same set of chained operations. The difference is that this time we locate a target droppable element and drop our clicked element on it by using move_to_element and release. We again used the move_by_offset here to adjust the position so that the asserted message “dropped!” is visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Scalable Automation Testing On Cloud
&lt;/h2&gt;

&lt;p&gt;To carry out automated tests in a highly scalable manner on a wide number of browsers and operating system environments, you can use LambdaTest’s automated cross browser testing solution on the cloud.&lt;/p&gt;

&lt;p&gt;To execute the above script on LambdaTest, we need to modify setUp() function to the following –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def setUp(self):
        username = "your_lambdatest_username"
        # Register on lambdatest, if you’ve not already. It hardly takes 30 seconds to 2 minutes to get started.
        accessToken = "your_lambdatest_accessToken"
        # You can find access token post registration on your LambdaTest profile page.
        gridUrl = "hub.lambdatest.com/wd/hub"
        desired_cap = {
            'platform' : "win10",
            'browserName' : "chrome",
            'version' :  "67.0",
            "resolution": "1024x768",
            "name": "LambdaTest python selenium drag and drop test ",
            "build": "LambdaTest python selenium drag and drop actionChains",
            "network": True,
            "video": True,
            "visual": True,
            "console": True,
        }
        # Desired capabilities dictionary specifies details of the testing environment. Manipulate this  dictionary to cross-test on multiple browsers and OS’s.
        url = "https://"+username+":"+accessToken+"@"+gridUrl 
        print("Initiating remote driver on platform: "+desired_cap["platform"]+" browser: "+desired_cap["browserName"]+" version: "+desired_cap["version"])
        self.driver = webdriver.Remote(
            desired_capabilities=desired_cap,
            command_executor= url
        )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Registration and setup have been explained in this JavaScript alert handling with Selenium article.&lt;/p&gt;

&lt;p&gt;The above script, when executed in LambdaTest cloud and under specified desired capabilities, yields –&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fimage2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fimage2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up!
&lt;/h2&gt;

&lt;p&gt;We hope you are all set to start dragging and dropping without any manual effort. The best part is that you need not worry about maintaining environments and browser versions. Just focus on the crucial part, i.e., writing the test cases using a manageable &lt;a href="https://www.lambdatest.com/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-21012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;cross browser testing&lt;/a&gt; environment provider like LambdaTest. Not to mention, cross browser testing using Selenium WebDriver by self hosting in the cloud is a cost-ineffective and resource-intensive process.&lt;/p&gt;

&lt;p&gt;Using a cloud-based platform like LambdaTest takes away all Ops pain and enables automation testing engineers to do what they do the best- write the application testing scripts and automate the cross browser testing process on over 2000+ browsers on the cloud.&lt;/p&gt;

&lt;p&gt;We hope that this post convinces you to try this drag and drop gesture. And if you did find it valuable, we’ll be grateful if you could share it on your LinkedIn or Twitter. Remember, sharing is caring!&lt;/p&gt;

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

</description>
      <category>python</category>
      <category>selenium</category>
      <category>automation</category>
      <category>testing</category>
    </item>
    <item>
      <title>Top 10 CI/CD Pipeline Implementation Challenges And Solutions</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Tue, 19 Jan 2021 10:19:31 +0000</pubDate>
      <link>https://forem.com/codepoetn/top-10-ci-cd-pipeline-implementation-challenges-and-solutions-5h3f</link>
      <guid>https://forem.com/codepoetn/top-10-ci-cd-pipeline-implementation-challenges-and-solutions-5h3f</guid>
      <description>&lt;p&gt;CI/CD pipelines have become the mainstream approach to software development across the entire IT sector. There’s no doubt that CI/CD pipeline tools have matured a lot over the years. Yet, developers, QA engineers, and leaders are still posed with some challenges and roadblocks in adopting and efficiently implementing CI/CD tools. This article highlights the top 10 CI/CD challenges that people face during implementation, and we will also discuss their potential solutions.&lt;/p&gt;

&lt;p&gt;Let’s get started with the basics!&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is A CI/CD Pipeline?
&lt;/h2&gt;

&lt;p&gt;Traditionally, the software was developed using waterfall methodology but recently, agile and lean have started dominating the software development space. Today, DevOps practices play a crucial role in enabling this agile software development approach. To dive deeper into these methodologies, refer to our &lt;a href="https://www.lambdatest.com/blog/agile-vs-waterfall-methodology/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-19012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;Agile Vs Waterfall methodology&lt;/a&gt; comparison.&lt;/p&gt;

&lt;p&gt;Continuous integration &amp;amp; continuous delivery, i.e., CI/CD pipeline tools, technologies, and stages, are the pillars on which DevOps culture is architected. These are tools and technologies that eliminate the need to manually integrate different dependencies or manually test the code-base for security &amp;amp; design loopholes. CI/CD approach instead automates the entire operations process from integration to delivery, testing, and deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Continuous Integration?
&lt;/h2&gt;

&lt;p&gt;Continuous Integration (CI) is the kickoff step of CI/CD pipeline stages.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What does that mean?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When software is developed iteratively, development teams frequently code, build, test, release, and deploy features. Continuous Integration is all about automating this process by setting up a script-led mechanism to detect a change in the shared code repository automatically. Changes can be detected using polling, periodic monitoring, or using a push-out mechanism like webhooks.&lt;/p&gt;

&lt;p&gt;As soon as the change is detected, your CI solution automatically pulls up a copy of your updated code, builds it, carries out unit testing, and performs dependency compatibility checks to detect code loopholes at an early stage.&lt;br&gt;&lt;br&gt;
Continuous Integration (CI) can be implemented using open source tools like Jenkins or Continuous Integration SaaS services like Gitlab CI, Circle CI, or Codeship.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Continuous Delivery?
&lt;/h2&gt;

&lt;p&gt;Continuous Delivery (CD) stage of the CI/CD pipeline augments the benefits of continuous integration (CI) by expanding the scope of automation testing beyond unit testing.&lt;br&gt;&lt;br&gt;
Testing is not an inherent part of continuous integration. Still, DevOps teams prefer practicing unit testing at the integration level to identify code bugs and make the application more robust. Continuous Delivery incorporates automated load testing, API testing, integration testing, etc., besides unit testing.&lt;/p&gt;

&lt;p&gt;The pulse of Continuous Delivery lies in automating the entire software release cycle by triggering automated flows for building, testing, and staging code updates as soon as it surpasses continuous integration (CI). The CI/CD pipeline’s direct benefits are in pushing validated, secure, robust, and deployment-ready applications at a faster pace to the staging or pre-production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Continuous Deployment?
&lt;/h2&gt;

&lt;p&gt;Continuous Deployment (CD) further expands the scope of &lt;a href="https://www.lambdatest.com/blog/what-is-continuous-integration-and-continuous-delivery/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-19012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;continuous integration and continuous delivery&lt;/a&gt;. Continuous deployment is the final stage in a CI/CD pipeline process. Continuous deployment is a test-driven approach to validate the application on different parameters and automatically roll out deployments.&lt;/p&gt;

&lt;p&gt;A robust continuous deployment implementation incorporates continuous monitoring and alert features to automatically transition back to previous versions of deployment if any issue arises. There are also certain continuous deployment challenges that need to be addressed carefully. We will discuss these issues later in the next sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Continuous Testing?
&lt;/h2&gt;

&lt;p&gt;Be it integration, delivery, or deployment – testing has been an integral part of all the CI/CD pipeline stages. Continuous testing is an approach to automate the application testing process and embed it into the CI/CD pipeline to achieve greater agility.&lt;/p&gt;

&lt;p&gt;Different types of automated testing can and should be implemented at different CI/CD pipeline stages, making it easier to overcome CI/CD challenges. For instance, unit testing is more suited at the continuous integration stage of the CI/CD pipeline. Unit testing at this stage typically involves testing and validating code in isolation, i.e., independent of any other code. Integration testing, functional testing, and acceptance testing could be part of the continuous delivery and continuous deployment stage of the CI/CD pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common CI/CD Challenges (Including Continuous Deployment Challenges)
&lt;/h2&gt;

&lt;p&gt;Adhering to the CI/CD approach of agile software development is not always a cake-walk. Having understood the CI/CD pipeline terminologies and overall flow in detail, let’s now acquaint ourselves with some common CI/CD challenges –&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Limited Environment Challenges
&lt;/h3&gt;

&lt;p&gt;Software development teams, especially testers, often get only limited infrastructure resources to test their code. In such scenarios, teams tend to incline towards a shared testing environment.&lt;/p&gt;

&lt;p&gt;Shared testing environments are not always that smooth an experience with CI/CD pipeline. There are a lot of continuous deployment challenges associated with it. Several developers and teams (if the project is way too large) are concurrently committing code to the same CI environment. Sometimes, several &lt;a href="https://www.lambdatest.com/blog/what-is-parallel-testing-and-why-to-adopt-it/" rel="noopener noreferrer"&gt;parallel testings&lt;/a&gt; are in process. This could branch into environment configuration issues as different tests might need different environment configurations.&lt;/p&gt;

&lt;p&gt;In fact, more than often, the poor configuration of the shared testing environment translates into failed tests &amp;amp; failed deployments in-turn. This dilutes the very purpose of the CI/CD approach, i.e., faster iterative development.&lt;/p&gt;

&lt;p&gt;A solution to this could be on-demand or on-need-basis dedicated testing environment creation in the cloud. LambdaTest’s Selenium automation testing features could bring relief to testing teams facing CI/CD challenges like limited testing environments or inefficient implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ownership-Based CI/CD Challenges
&lt;/h3&gt;

&lt;p&gt;Often bugs and code errors are identified at a later stage of the DevOps release cycle. Sometimes, CI/CD pipeline even fails or breaks down due to these bugs. Failing pipelines are normal. It is designed to break if all the code is not integrable and if the code is not securely performing its intended functions.&lt;/p&gt;

&lt;p&gt;But poor CI/CD pipeline implementation often makes it a cumbersome task to identify failure cause immediately. This, in turn, makes it harder to redirect to the concerned teams for fixing code errors.&lt;/p&gt;

&lt;p&gt;A quick fix to this CI/CD challenge is to ensure that code and test-cases are written with easily identifiable logging capabilities. Assign ownership roles to individuals or teams for each stage of the CI/CD pipeline. Based on the failure log analysis, these individuals will be responsible for figuring out the failure cause, identifying, and redirecting the team responsible for fixing the continuous deployment challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Implementing Multiple CI/CD Pipelines For Large Scale Projects
&lt;/h3&gt;

&lt;p&gt;In big enterprises, several large scale projects are parallelly under development and maintenance. And multiple development teams are incrementally committing changes to the respective code repositories. So if issues get introduced in the commit, compile, build, test, deliver, deploy cycle, it is often tough to analyze it and get to the root cause.&lt;/p&gt;

&lt;p&gt;This is one of the major CI/CD challenges when it comes to enterprise-level organizations. As a solution, teams can have standard CI/CD pipeline templates across the organization and break down complex, massive projects into smaller modules. This enables meaningful reporting and fastens up feedback cycles for improving code and fixing issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Integrating Security Tools
&lt;/h3&gt;

&lt;p&gt;In a study by 451 Research, more than 60% of respondents said a lack of automated, integrated security tools is a big challenge in implementing CI/CD tools effectively.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FIntegrating-Security-Tools.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FIntegrating-Security-Tools.png" alt="Integrating Security Tools" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Security tests like static application security test (SAST), software composition analysis test (SCA), and dynamic application security test (DAST) are deployable at different stages of the CI/CD pipeline on need-basis.&lt;/p&gt;

&lt;p&gt;SAST &amp;amp; SCA are responsible for ensuring security tests at the CI stage and taking care of pre-commit checks and incremental tests at commit and build stages of the CI/CD pipeline. DAST &amp;amp; IAST are responsible for fuzz testing, pen-testing, hardening, etc.&lt;/p&gt;

&lt;p&gt;The security challenge highlighted by 451 research is an inefficient security implementation and sometimes misleading information in terms of “false positives.” These issues could be resolved by properly identifying which security testing tool best fits in with your remaining CI/CD tools. The tools must be configured to automatically update the defect tracking system, break the build if it identifies crucial security threats, and update the metrics monitoring dashboard. This would enable responsible teams to act immediately on the identified threats and overcome a major continuous deployment challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Coordination-Based CI/CD Challenges
&lt;/h3&gt;

&lt;p&gt;CI and CD are often implemented separately by teams, and the tools and processes need to be compatible with incremental feedback-led processes.&lt;/p&gt;

&lt;p&gt;Apart from tools in the continuously iterative development, poor communication across business and product teams also leads to delayed-release and deployment cycles. One of the big benefits of the CI/CD pipeline is accelerated delivery and deployment cycle, but lack of coordination fails the use-case. In large projects, companies have critical data and software in databases and on servers.&lt;/p&gt;

&lt;p&gt;When the build or test-cases fail, teams responsible for addressing failed builds don’t have access to these critical resources for obvious security reasons. But these challenges can be addressed with proper coordination among teams and automated processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Cost &amp;amp; Resource Management
&lt;/h3&gt;

&lt;p&gt;Implementing CI/CD across the organization has long-term benefits in business agility, product robustness, security, and feature release cycle, but it also has associated costs. The resources, tools, and infrastructure requirements significantly add up to the project costs.&lt;/p&gt;

&lt;p&gt;Besides, everyone has their own preference for tools and other resources as per their convenience. Also, adopting CI/CD doesn’t always mean better agility. It can potentially slow down processes and deter dev productivity if proper guidance and training are not available to developers and executives.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Implementing CI/CD Into Ongoing Projects &amp;amp; Workflows
&lt;/h3&gt;

&lt;p&gt;Going agile, adopting, and implementing CI/CD pipelines to existing workflows and projects is not an easy task either. Especially in large scale legacy projects and workflows, changes to any part might need changes across several other processes and workflows.&lt;/p&gt;

&lt;p&gt;This inevitably requires extreme caution, in-depth knowledge, and rich experience with CI/CD tools as the stakes in terms of costs, latency, and quality are quite high.&lt;/p&gt;

&lt;p&gt;Companies and teams should impartially evaluate if they really need CI/CD and if it would augment their processes and development approach. If the answer is yes, they should evaluate feasibility too in terms of costs and infrastructure resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Training, Cultural &amp;amp; Other Internal Resistance
&lt;/h3&gt;

&lt;p&gt;Developers normally don’t enjoy doing operations tasks, but in CI/CD approach, developers often need to intervene and get involved with configuring VMs and other environments.&lt;/p&gt;

&lt;p&gt;As CI/CD tools are relatively new in the market, there is not much expertise and training available, which again is a challenge as poor CI/CD implementation would add up costs and risks.&lt;/p&gt;

&lt;p&gt;Also, companies face internal resistance from developers, team leads, and other project stakeholders as implementing CI/CD is a new approach for them and pushes them out of their comfort zone.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Inefficient Implementation Of CI/CD Pipelines
&lt;/h3&gt;

&lt;p&gt;Lack of expertise, poor training, and several other challenges could lead to the inefficient implementation of CI/CD pipelines. Teams are seen automating wrong processes, writing flawed test cases, configuring CI in a wrong way, and even mistaking between continuous delivery approach and continuous deployment concept.&lt;/p&gt;

&lt;p&gt;For instance, automated deployment need not be triggered with each successful delivery because there can be several commits a day. You cannot release 10 versions of a product for users on the same day or even over weeks. This is another major continuous deployment challenge that needs to be resolved at the earliest. The delivery stage is to always be in a deployment-ready state. The deployment stage is more of a business decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Continuous Testing &amp;amp; Optimization
&lt;/h3&gt;

&lt;p&gt;Poorly written unit tests and acceptance tests could be a bottleneck to feedback-led iterative software development. However, it is more of the testing team’s internal problems rather than CI/CD challenges. But solely focusing on functional tests is a bad continuous testing practice for CI/CD pipelines. Test cases should also be written for non-functional requirements like performance measuring &amp;amp; reliability tests.&lt;/p&gt;

&lt;p&gt;Performance features could be very critical in banking and healthcare applications. Writing test cases for performance tests &amp;amp; reliability tests are not as straightforward as testing functional requirements. These also need large testing environments to test application scalability, reliability, and various test-failure scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  How LambdaTest’s Integration In Your Pipeline Will Resolve CI/CD Challenges?
&lt;/h2&gt;

&lt;p&gt;LambdaTest is a cross browser compatibility testing tool. It enables you to interactively test your web and mobile applications on all major browsers for different mobile operating systems like Android, iOS, and desktop environments like Mac, Windows, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FLambdaTest%25E2%2580%2599s-Integration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2FLambdaTest%25E2%2580%2599s-Integration.png" alt="LambdaTest’s Integration" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;LambdaTest provides you out-of-the-box automated testing solutions to easily integrate with a suite of applications, from bug logging to project management tools &amp;amp; dashboards. Also, as already mentioned, LambdaTest integrates with CI tools of your choice to make automated testing a seamless experience for you.&lt;/p&gt;

&lt;p&gt;One of the best ways to overcome the most common CI/CD challenges is using cloud-based automation testing platforms that allow easy integration with CI/CD tools. For example, LambdaTest offers you a suite of automation testing services in the cloud to test your software across 2000+ browsers &amp;amp; devices using a &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=Nishant-19012021&amp;amp;utm_term=Nishant" rel="noopener noreferrer"&gt;cloud Selenium Grid&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fcloud-Selenium-Grid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F11%2Fcloud-Selenium-Grid.png" alt="cloud Selenium Grid" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  That Is All!
&lt;/h2&gt;

&lt;p&gt;To conclude, most of the CI/CD challenges are related to poor practices and poor implementation. Properly evaluating CI/CD requirements and choosing the right tools, correctly configuring CI/CD pipeline stages, and rightly training the concerned professionals will lead to a successful CI/CD implementation. So you as an organization could focus more on shipping features than on controlling operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Utilize the power of Automation, leverage Automated testing.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
    </item>
    <item>
      <title>How To Take A Screenshot Using Python &amp; Selenium?</title>
      <dc:creator>codepoetn</dc:creator>
      <pubDate>Wed, 21 Oct 2020 10:01:39 +0000</pubDate>
      <link>https://forem.com/codepoetn/how-to-take-a-screenshot-using-python-selenium-3nec</link>
      <guid>https://forem.com/codepoetn/how-to-take-a-screenshot-using-python-selenium-3nec</guid>
      <description>&lt;p&gt;The goto software framework for any web developer looking for an open-source, free test automation tool is Selenium. It is used with various programming languages, including Java, Python, PHP, Perl, and C#. Selenium can also be used as a web-scraping tool or to create a human-replica bot to automate social-media or even test PDF files ! Geeks at Google &amp;amp; Thoughtworks are highly credited for its development and maintenance.&lt;/p&gt;

&lt;p&gt;In this Python Selenium screenshot tutorial, we are going to explore different ways of taking screenshots using Selenium’s Python bindings. Before we hop-on to capturing Python Selenium screenshots, let’s first acquaint ourselves with Selenium Python bindings.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Selenium Python Bindings?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.lambdatest.com/blog/tips-for-test-automation-with-selenium/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=SM-21102020&amp;amp;utm_term=SM" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt;has different components; we have Selenium WebDriver, Selenium IDE, and Selenium Grid. Selenium Python bindings is an API interface to use Python with Selenium WebDriver for writing functional/acceptance tests. We shall be using these Python bindings for Selenium to capture full page screenshots, HTML element-specific screenshots and save it in our desired location.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we learn how to use Selenium Python for taking screenshots, we need to install some dependencies. Below is a list of all that you need in your machine-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python &lt;/li&gt;
&lt;li&gt;Pip&lt;/li&gt;
&lt;li&gt;Selenium Python bindings&lt;/li&gt;
&lt;li&gt;GeckoDriver &lt;/li&gt;
&lt;li&gt;ChromeDriver &lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;For learning how to use Selenium Python, you must have Python &amp;amp; pip installed on your system or server. Python comes pre-installed with Linux &amp;amp; Mac systems. For Windows, you may download the Python installer from &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FPython.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FPython.png" alt="Python" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Python 2 is redundant now. So, if your Linux or Mac system is having the older version, you may consider updating them to the latest stable versions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You would also need pip installed on your system.pip is a tool or a package manager tool for Python and it comes pre-installed with the latest versions (as you can see in the image above). You can check if it is existing in your system by running following command in the command prompt-&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;pip help&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you get a response like below from pip, you are good to go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2Fimage.0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2Fimage.0.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If it displays something like this-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2Fpip-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2Fpip-1.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you have to download this get-pip.py &lt;a href="https://pip.pypa.io/en/stable/installing/" rel="noopener noreferrer"&gt;file&lt;/a&gt; to any location in your system, but you should have the path to the file. Remember, you only have to do this if pip is not installed in your system.&lt;/p&gt;

&lt;p&gt;Next, run this command to install pip.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python get-pip.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you aren’t in the directory as that of the downloaded file, replace the file name in the command given above with the full path to the file location.&lt;/p&gt;

&lt;p&gt;Now try the command pip help again, you should see the screen we shared earlier.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, we install Selenium Python bindings using pip. Then, you will have to run this command-&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;pip install selenium&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This installs Selenium’s Python bindings in your system. Alternatively, if you don’t like this installation mechanism, you may first download the Selenium-Python source distribution from &lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;Pypi&lt;/a&gt;. Unarchive it. Once you do this, run the following command to install the bindings –&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python setup.py install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Again, remember you only need this if you don’t want to install using pip. Also, if you are not in the same folder where you have archived the downloaded Selenium Python bindings then replace setup.py with full path to setup.py.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, we need a driver to proceed with clicking Python Selenium screenshots of webpages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can choose any browser of your choice, and you can download the drivers from the following links :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sites.google.com/a/chromium.org/chromedriver/" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mozilla/geckodriver/releases" rel="noopener noreferrer"&gt;Firefox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/" rel="noopener noreferrer"&gt;Edge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://selenium-release.storage.googleapis.com/index.html" rel="noopener noreferrer"&gt;Internet Explorer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let’s make a trial file named check_setup.py. Write the following code in it –&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver browser = webdriver.Firefox() browser.get(“https://www.lambdatest.com/”) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should fire-up a Firefox instance and automatically load the LambdaTest homepage. If this worked for you, we’re all set to capture Python Selenium screenshots of websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capturing Screenshots Using Python &amp;amp; Selenium
&lt;/h2&gt;

&lt;p&gt;I hope that now you have all the dependencies installed and know how to use Selenium Python, it is time to get to the good part. In this section, we will see how to take a Python Selenium screenshot for any web page. We will see instances for both GeckoDriver &amp;amp; ChromeDriver. First, let’s see how to use Selenium Python with GeckoDriver or Selenium FirefoxDriver.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using get_screenshot_as_file() with GeckoDriver For Python Selenium Screenshots
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver 
from time import sleep 
browser = webdriver.Firefox() 
browser.get(“https://www.lambdatest.com/”) 
sleep(1) 
browser.get_screenshot_as_file(“LambdaTestVisibleScreen.png”) 
browser.quit() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would like to store these images in a specific location other than the project directory, please specify full path as the argument to get_screenshot_as_file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Walkthrough:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s understand what we are doing here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from selenium import webdriver&lt;/code&gt; – This line imports the WebDriver which we use to fire-up a browser instance and use APIs to interact with web elements.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from time import sleep&lt;/code&gt; – This line imports the sleep function from Python’s ‘time’ module. This accepts integer arguments which equals the number of seconds. The script waits for the specified number of seconds before executing the next line of code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;browser = webdriver.Firefox()&lt;/code&gt; – This line is equivalent to saying, use the keyword ‘browser’ as you would use ‘webdriver.Firefox()’.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;browser.get(“https://www.lambdatest.com/”)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This fires-up a Firefox instance controlled by a Selenium driver and fetches the URL specified as an argument to get(argument) function.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sleep(1)&lt;/code&gt; – This halts the script from running for 1 sec. This step is often required when there are animations on the page or when you explicitly want to wait for a while so that some actions can be performed or pages can load fully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;a href="https://www.lambdatest.com/blog/tips-for-test-automation-with-selenium/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=SM-21102020&amp;amp;utm_term=SM" rel="noopener noreferrer"&gt;Selenium WebDriver&lt;/a&gt; by default waits for the page to load completely before executing the next line of script or operation. But in some advanced JavaScript rendered websites, we may need to use ‘sleep’ for manually pausing the script for a while so that animations and the page itself is fully loaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;browser.get_screenshot_as_file(“LambdaTestVisibleScreen.png”) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This finally clicks the visible section of the webpage in the launched Firefox instance and saves the screenshot with specified name and extension.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;browser.quit()&lt;/code&gt;– Lastly, the browser needs to be closed and this line does the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using save_screenshot() with GeckoDriver For Python Selenium Screenshots
&lt;/h3&gt;

&lt;p&gt;This is the easiest way to save the full page screenshot. Just replace the get_screenshot_as_file command with save_screenshot, as displayed below-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;browser.get_screenshot_as_file(“LambdaTestVisibleScreen.png”) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;driver.save_screenshot(‘your_desired_filename.png’) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will see how to use Selenium Python to capture screenshots with the help of Selenium ChromeDriver.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using screenshot() With ChromeDriver For Python Selenium Screenshots
&lt;/h3&gt;

&lt;p&gt;‘save_screenshot’ function works with ChromeDriver, but to propose an alternative solution, we will also show you how to use the screenshot function to take a full-page screenshot. Here is the script-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver 
from time import sleep 
from selenium.webdriver import ChromeOptions 
options = ChromeOptions() 
options.headless = True 
browser = webdriver.Chrome(chrome_options=options) 
URI = “https://www.lambdatest.com/” 
browser.get(URI) 
sleep(1)
S = lambda X: browser.execute_script(‘return document.body.parentNode.scroll’+X) browser.set_window_size(S(‘width’), S(‘height’)) 
browser.find_element_by_tag_name(‘body’).screenshot(‘LambdaTestFullPage.png’) browser.quit() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Walkthrough:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s understand what we are doing here. First of all, in this example, we are using ChromeDriver. Earlier we had used a GeckoDriver for using Firefox as a browser. More or less, the other functionalities are the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium.webdriver import ChromeOptions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We import ChromeOptions to set the browser as headless so that it runs in the background. We could have directly used webdriver.ChromeOptions, but to make it more understandable we split it into a separate line of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;options = ChromeOptions() 
options.headless = True 
browser = webdriver.Chrome(chrome_options=options) 
URI = “https://www.lambdatest.com/” 
browser.get(URI) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use the newly set ChromeOptions and pass it as parameter to the webdriver’s Chrome function. Observe, previously we used “Firefox()”. “Browser.get” launches the instance and fetches the URI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;S = lambda X: browser.execute_script(‘return document.body.parentNode.scroll’+X) browser.set_window_size(S(‘width’), S(‘height’)) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line is a lambda function to find the value of X. We get the value by executing DOM JavaScript functions. The second line is to resize the window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;browser.find_element_by_tag_name(‘body’).screenshot(‘lambdaTestFullPage.png’) browser.quit() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we track down the body element of the webpage by using the driver function find_element_by_tag_name and pass “body” as parameter. You could also use find_element_by_id, find_element_by_xpath to locate the element.&lt;br&gt;&lt;br&gt;
We used a ‘.’ operator nested screenshot() function in the same line to capture the full page screenshot. Lastly, we terminate the Chrome instance using &lt;code&gt;browser.quit()&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Capturing Python Selenium Screenshots Of A Particular Element
&lt;/h2&gt;

&lt;p&gt;We now demonstrate how we can use the &lt;code&gt;save_screenshot()&lt;/code&gt; function to capture any element on the page, say a button or an image or a form, anything. We shall use Python’s PIL library which lets us perform image operations.&lt;/p&gt;

&lt;p&gt;We shall capture a feature “section” element on LambdaTest website with following XPath – “//section[contains(string(),’START SCREENSHOT TESTING’)]”&lt;/p&gt;

&lt;p&gt;The final script would be :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver 
from time import sleep 
from PIL import Image 
browser = webdriver.Chrome() 
browser.get(“https://www.lambdatest.com/feature”) 
sleep(1) 
featureElement = browser.find_element_by_xpath(“//section[contains(string(),’START SCREENSHOT TESTING’)]”) 
location = featureElement .location 
size = featureElement .size 
browser.save_screenshot(“fullPageScreenshot.png”) 
x = location[‘x’] 
y = location[‘y’] 
w = x + size[‘width’] 
h = y + size[‘height’] 
fullImg = Image.open(“fullPageScreenshot.png”) 
cropImg = fullImg.crop(x, y, w, h) 
cropImg.save(‘cropImage.png’) 
browser.quit()  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script when executed would save the cropped info-element from LambdaTest website as cropImage.png.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Walkthrough:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from PIL import Image&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This line imports the Image module from PIL library of Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;featureElement = browser.find_element_by_xpath(“//section[contains(string(),’START SCREENSHOT TESTING’)]”)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line locates one of the features on LambdaTest website using XPath (as you can see below.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FScreenshot-132.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FScreenshot-132.png" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location = featureElement .location 
size = featureElement .size 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First-line fetches the vertical and horizontal start location of the feature-element. Second line gets the width and height of the element.&lt;/p&gt;

&lt;p&gt;We store these in ‘x’, ’y’, ’w’, ‘h’ variables respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fullImg = Image.open(“fullPageScreenshot.png”) 
cropImg = fullImg.crop(x, y, w, h) 
cropImg.save(‘cropImage.png’)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We first open the image and store bytes in a “fullImg” variable. Next we crop it using the x,y,w,h parameters we calculated.&lt;/p&gt;

&lt;p&gt;Lastly, we save the cropped image.&lt;/p&gt;

&lt;p&gt;This should be the output that you will see after the successful execution of the code-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FScreenshot-133.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.lambdatest.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F10%2FScreenshot-133.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Role Do Screenshots Play In Test Automation?
&lt;/h2&gt;

&lt;p&gt;Automated screenshots could help in easy identification of the bugs and faster doing it all manually. Most importantly, it can be as scalable as the application you are testing without requiring extra testers. A direct implication of all above is – automated screenshots are a cost-effective and time-efficient process.&lt;/p&gt;

&lt;p&gt;Additionally,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s always a better alternative to manually opening the websites in different browsers and saving the images. &lt;/li&gt;
&lt;li&gt;For responsive applications, which need to run across devices and have many different themed pages and components, taking screenshots makes sense.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other Options To Take Python Selenium Screenshots
&lt;/h3&gt;

&lt;p&gt;If you would rather use other ways to capture Python Selenium screenshots, you can also use this &lt;a href="https://pypi.org/project/Selenium-Screenshot/" rel="noopener noreferrer"&gt;library&lt;/a&gt;to take screenshots. For installing it, execute the following command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install Selenium-Screenshot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example to Capture Full-Page Screenshot:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from Screenshot import Screenshot_Clipping 
from selenium import webdriver
ob=Screenshot_Clipping.Screenshot() 
driver = webdriver.Chrome() 
url = "https://www.google.com" 
driver.get(url) 
img_url=ob.full_Screenshot(driver, save_path=r'.', image_name='google.png') 
driver.quit() 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Selenium &amp;amp; Python Are Well-Suited For Capturing Screenshots?
&lt;/h2&gt;

&lt;p&gt;Selenium and Python are the goto choices when it comes to &lt;a href="https://www.lambdatest.com/selenium-automation?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=SM-21102020&amp;amp;utm_term=SM" rel="noopener noreferrer"&gt;Selenium test automation&lt;/a&gt;. And this is not just limited to capturing screenshots, there’s a lot more you can do using this awesome combination. Let’s find out why-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The learning curve is very small for Selenium Python bindings as the language itself is very easy and intuitive to start with.&lt;/li&gt;
&lt;li&gt;We can use it with multiple browsers including the popular ones.&lt;/li&gt;
&lt;li&gt;The number of lines of code you need to write in Python is far less than compared to other languages. &lt;/li&gt;
&lt;li&gt;Strong community support.&lt;/li&gt;
&lt;li&gt;Faster &amp;amp; efficient execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap Up!
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we learned about using Selenium and Python to capture screenshots of web pages. This is essentially the best way to catch bugs efficiently and save your team a lot of time. The best way to perform &lt;a href="https://www.lambdatest.com/?utm_source=dev&amp;amp;utm_medium=Blog&amp;amp;utm_campaign=SM-21102020&amp;amp;utm_term=SM" rel="noopener noreferrer"&gt;cross browser testing&lt;/a&gt; is to compare how the web pages are rendered over multiple browsers or devices.&lt;/p&gt;

&lt;p&gt;You can use a cloud-based platform like LambdaTest to capture your website’s screenshots or a particular web page without going through the trouble of writing the code. You can do this on a selection of 2000+ browsers and operating systems over a Selenium Grid cloud. We hope these tools will come in handy when you are not in the mood to write all that code but just want to hunt some bugs!&lt;/p&gt;

&lt;p&gt;If you have any issues or questions don’t hesitate to reach out via the comment section.&lt;br&gt;&lt;br&gt;
Happy testing!&lt;/p&gt;

</description>
      <category>selenium</category>
      <category>automationtesting</category>
      <category>seleniumwebdriver</category>
      <category>python</category>
    </item>
  </channel>
</rss>
