<?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>DEV Community: Sam E. Lawrence</title>
    <description>The latest articles on DEV Community by Sam E. Lawrence (@samelawrence).</description>
    <link>https://dev.to/samelawrence</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%2F131165%2F654e1ebb-5f17-490e-92ea-b190cd217d49.png</url>
      <title>DEV Community: Sam E. Lawrence</title>
      <link>https://dev.to/samelawrence</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samelawrence"/>
    <language>en</language>
    <item>
      <title>On proactively naming elements within Cypress '.within()' blocks</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Thu, 26 Dec 2024 08:23:07 +0000</pubDate>
      <link>https://dev.to/samelawrence/on-proactively-naming-elements-within-cypress-within-blocks-2mp1</link>
      <guid>https://dev.to/samelawrence/on-proactively-naming-elements-within-cypress-within-blocks-2mp1</guid>
      <description>&lt;p&gt;Anytime you use &lt;code&gt;.within()&lt;/code&gt; in a Cypress test, you have the option to name the element variable that you pass into the function &lt;strong&gt;body&lt;/strong&gt;. Here's an example where the element scope is named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#el&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;within&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;optionallyNamedElement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but here's another perfectly functional example where it isn't:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#el&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;within&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the named element term isn't used in the function body, should we assign it a name when we write this test code? I think we should.&lt;/p&gt;

&lt;p&gt;It's ok if someone comes along later and changes this name, but I think it's a courtesy to future programmers to give them a semantic name here for future use. This name might use a consistent style across the test codebase, or just provide a way for a future programmer to avoid getting stuck in future by having to pause to come up with a name. Remember, that future programmer might be you!&lt;/p&gt;

&lt;p&gt;I also think that proactively providing a name here makes code more &lt;em&gt;clear&lt;/em&gt;, &lt;em&gt;approachable&lt;/em&gt;, and &lt;em&gt;debuggable&lt;/em&gt;. By naming the element, when a bug arises, you at least have a clue of what element you &lt;strong&gt;thought&lt;/strong&gt; you were scoped within.&lt;/p&gt;

&lt;p&gt;When I use &lt;code&gt;.within()&lt;/code&gt; these days, I always try to remember to name the scope that I'm entering, even when that variable never gets used in the function body.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>My QA Tech Stack in 2025</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Fri, 29 Nov 2024 19:08:36 +0000</pubDate>
      <link>https://dev.to/samelawrence/my-qa-tech-stack-in-2025-ee2</link>
      <guid>https://dev.to/samelawrence/my-qa-tech-stack-in-2025-ee2</guid>
      <description>&lt;p&gt;When I made an &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7239044490030698497/" rel="noopener noreferrer"&gt;initial version of this post&lt;/a&gt; on my &lt;a href="https://www.linkedin.com/in/samelawrence/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, it got a lot of attention including comments from some of the companies who make my favorite work tools. I asked folks if they'd like to see an expanded blog post with more of my thoughts on the tools I use, so this is that post.&lt;/p&gt;

&lt;p&gt;As we go into 2025, here (in no particular order) is my QA tool stack:&lt;/p&gt;

&lt;h2&gt;
  
  
  Cypress
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.cypress.io/" rel="noopener noreferrer"&gt;Cypress&lt;/a&gt; has been my go-to tool for test automation on web projects for several years now. It has a simple, expressive API but also contains some very powerful features for when you want to get deeper, and above all, it allows me to get things done quickly. I haven't taken a deep look at Playwright, so things may change in the future, but for now I'm very satisfied with Cypress and plan to continue using it in 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt; is obviously where my team and I store our test code, but also make use of its powerful Github Actions pipeline features to run our tests on a schedule, or kick off runs against targeted environments. We also love the code review tooling and collaborate on code frequently.&lt;/p&gt;

&lt;h2&gt;
  
  
  VS Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt; is my preferred IDE and I recommend it to my team. Additionally, we use &lt;a href="https://prettier.io/" rel="noopener noreferrer"&gt;Prettier&lt;/a&gt; to enforce consistent, clean code style across our projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qase
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://qase.io/" rel="noopener noreferrer"&gt;Qase&lt;/a&gt; is a lightweight but powerful test management tool with fairly decent reporting capabilities. In addition to test run reports, I love their dashboard features which allow me to check on automation progress and other key metrics at a glance. Our team was previously using &lt;a href="https://www.testrail.com/" rel="noopener noreferrer"&gt;TestRail&lt;/a&gt;, but we made the switch and haven't looked back.&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%2Fdrztq7y5kax7zdac0u0w.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%2Fdrztq7y5kax7zdac0u0w.png" alt="A screenshot of a Qase dashboard" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Shortcut
&lt;/h2&gt;

&lt;p&gt;If you aren't using &lt;a href="https://www.shortcut.com/" rel="noopener noreferrer"&gt;Shortcut&lt;/a&gt;, seriously take a look at it, it's great. Our engineering team manages all our work in this Trello/Jira competitor. As QA, we also use it for tracking our tasks like automation work, regression testing, and other chores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notion
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.notion.so/" rel="noopener noreferrer"&gt;Notion&lt;/a&gt; serves as a knowledge base and documentation hub for our whole company, and as QA we use it to document our practices and store some test data references. In particular, I love the ability to reference pages in other pages, creating a web of knowledge across all our documents - and with the native integration of &lt;a href="https://mermaid.js.org/" rel="noopener noreferrer"&gt;Mermaid.js&lt;/a&gt;, creating flowcharts is fun and easy.&lt;/p&gt;




&lt;p&gt;What tools do you use to get your QA work done? Let me know in the comments if you're using the same tools and techniques as my team, or if you have other tools you love to use!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>tooling</category>
      <category>career</category>
      <category>workplace</category>
    </item>
    <item>
      <title>Interaction between .skip() and after() in Cypress</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Thu, 25 Jul 2024 19:10:14 +0000</pubDate>
      <link>https://dev.to/samelawrence/interaction-between-skip-and-after-in-cypress-4k8c</link>
      <guid>https://dev.to/samelawrence/interaction-between-skip-and-after-in-cypress-4k8c</guid>
      <description>&lt;p&gt;I believe this is an issue that should be treated as a Cypress bug, but it has an easy-enough work-around, so I'm documenting my findings here as a blog post in case my learnings can be helpful to someone else.&lt;/p&gt;

&lt;p&gt;Most Cypress tests use a &lt;code&gt;beforeEach()&lt;/code&gt; hook to do things like login to a site, a series of &lt;code&gt;it()&lt;/code&gt; blocks to define the tests, and then perhaps an &lt;code&gt;after()&lt;/code&gt; hook to perform some data cleanup or reset state. While running tests in the desktop runner, it can be helpful to mark a test with &lt;code&gt;.only&lt;/code&gt; to selectively run it as you make changes. However, &lt;code&gt;.only&lt;/code&gt; will cause the entire spec to fail in headless mode, and therefore you must remove all usages of it before pushing your changes up to your CI environment.&lt;/p&gt;

&lt;p&gt;Sometimes a test needs to be removed from your suite, or perhaps you want to commit some code for a test that is incomplete and not ready to run. You might want to use &lt;code&gt;.skip&lt;/code&gt; to do that, but unlike &lt;code&gt;.only&lt;/code&gt; - this will work both for local headed test runs, and headless runs.&lt;/p&gt;

&lt;p&gt;So, let's imagine that you have some logic in an &lt;code&gt;after()&lt;/code&gt; hook, and it doesn't need to reauthorize the user, so you just use some commands that assume the browser still has the page open from the last run test in the suite. If that last test is marked with &lt;code&gt;.skip&lt;/code&gt;, your &lt;code&gt;after()&lt;/code&gt; hook will run just fine, because the local headed runner doesn't tear down the browser automatically after the last test, and any tests marked with &lt;code&gt;.skip&lt;/code&gt; will never launch any action at all.&lt;/p&gt;

&lt;p&gt;In headless runs, however, the page is torn down after each test, and skipped tests still do launch a browser page instance, though they never launch the &lt;code&gt;baseUrl&lt;/code&gt; or perform any actions. For this reason, in headless runs, an &lt;code&gt;after()&lt;/code&gt; block that is immediately preceded by a test marked with &lt;code&gt;.skip&lt;/code&gt; will only see the blank Cypress page, with no content loaded, and thus they cannot be expected to execute the way they would in a local headed run.&lt;/p&gt;

&lt;p&gt;The workaround for this is to treat your &lt;code&gt;after()&lt;/code&gt; hook exactly like your test cases, and replicate the login and page load commands from your &lt;code&gt;beforeEach()&lt;/code&gt; hook in your &lt;code&gt;after()&lt;/code&gt; hook. This will guarantee that you get back to the necessary app page and state before you perform your cleanup steps. This issue tripped me up when I first encountered it, I hope you don't run into it yourself after reading this.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Three reasons to remove old LinkedIn connections</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Wed, 24 Jul 2024 13:05:00 +0000</pubDate>
      <link>https://dev.to/samelawrence/three-reasons-to-remove-old-linkedin-connections-3jgl</link>
      <guid>https://dev.to/samelawrence/three-reasons-to-remove-old-linkedin-connections-3jgl</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;When I first joined LinkedIn, I was eager to add new connections and sent out requests to anyone who seemed interesting. Granted, this was also before LinkedIn added their "creator mode" (&lt;a href="https://www.linkedin.com/in/samelawrence/" rel="noopener noreferrer"&gt;follow me&lt;/a&gt;) which allows following other users without adding them as a two-way connection. Social media was new, and I was new to my career, so I very much had a "more the merrier" approach to how I made connections online.&lt;/p&gt;

&lt;p&gt;I wanted that "500+ connections" text on my profile, and made connections with people everywhere I went. New jobs, conferences, after-work bars, tech meetups, old college friends - they all got a LinkedIn request, and many of them accepted. I don't think I was alone in my habits, and the early social web was a really fun time and place to feel connected to other people. However, my feelings about data privacy have shifted over the years, and I now see several issues with the idea that more connections is always better.&lt;/p&gt;

&lt;p&gt;Everything I say here may also apply to Instagram, Twitter, Facebook, etc. depending on how you use those networks. On this blog I try to write to a professional audience and give advice related to careers, not personal lives - but these days it's all enmeshed on the web, so take from this whatever you find useful. If you're early in your career, recently changed careers, or just feel overwhelmed by the number of your online connections, perhaps some of these thoughts will be helpful to you. So, here are my three reasons for removing old LinkedIn connections:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Privacy hygiene
&lt;/h2&gt;

&lt;p&gt;I believe that most of us should want to have a private-first presence on the web. Doxxing, SWATing, identity theft, bullying, and stalking are all real issues that show up in real people's lives without them asking for it. Do yourself a favor and limit the ways the world can find you. LinkedIn should work for you, not you for it - so protect yourself by restricting how many strangers can see your work and life updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Improving network relevance
&lt;/h2&gt;

&lt;p&gt;Aim for quality over quantity. Having a smaller network of people whose interests are closer to yours can be much more valuable than a long list of people who are just acquaintances. If you're a content creator or thought leader in your industry, then sure, aim for a big audience - but that's what Twitter is for, or LinkedIn's creator mode. I'm talking about mutual connections here. Keep your circle small, and make every connection matter.&lt;/p&gt;

&lt;p&gt;Networks are bi-directional, so in addition to improving the quality of your &lt;em&gt;audience&lt;/em&gt;, you will also improve the signal/noise ratio of the posts that flow into your timeline. You'll be more able to focus on the content and connections that matter to you, and the opportunities that you'll stumble across will be so much more tailored to your actual career goals and personal interests.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Supporting a smaller, faster Internet
&lt;/h2&gt;

&lt;p&gt;By trimming down our digital connections, we can contribute to a faster, more efficient internet. Computers are fast, so I don't just mean that we reduce the number of bits sent over the wire (although we should be somewhat concerned about that), I'm more speaking about the information density of the world we live in. It's clear that we are overloading our brains with noise, and the internet is becoming less useful and less pleasant as a result. &lt;a href="https://thehistoryoftheweb.com/cool-urls-mean-something/" rel="noopener noreferrer"&gt;The web is precious&lt;/a&gt;, let's keep it good.&lt;/p&gt;

&lt;p&gt;When I talk about shrinking the web, I'm more talking about focusing and narrowing the amount of information we have to take in and process &lt;em&gt;as humans&lt;/em&gt; on a daily basis. Who cares how much data the computers have to deal with... although, you know... data centers do use energy and until we are free from fossil fuels, that might be a thing to consider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's reconnect with purpose
&lt;/h2&gt;

&lt;p&gt;These are the reasons why I have intentionally reduced the number of connections I maintain on LinkedIn, and hopefully I've conveyed my general attitude toward how I see my social connections across the web. I encourage you to be intentional about reconnecting with old contacts, but feel no need to maintain connections that no longer serve a purpose.&lt;/p&gt;

&lt;p&gt;A smaller network can lead to stronger, more supportive professional relationships, and by focusing on these these relationships we can all practice better privacy, data hygiene, and professional purpose.&lt;/p&gt;

</description>
      <category>career</category>
      <category>socialmedia</category>
    </item>
    <item>
      <title>My Favorite Interview Questions for QA Engineers</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Wed, 24 Jul 2024 00:17:59 +0000</pubDate>
      <link>https://dev.to/samelawrence/my-favorite-interview-questions-for-qa-engineers-485a</link>
      <guid>https://dev.to/samelawrence/my-favorite-interview-questions-for-qa-engineers-485a</guid>
      <description>&lt;h2&gt;
  
  
  About this post
&lt;/h2&gt;

&lt;p&gt;I've been working in the field of software quality since 2013, starting out as a junior QA engineer/analyst doing a lot of manual grunt-work testing. Over the years, I've grown as an engineer, worked in a few different automation tools and moved around between companies. Now, as a Lead QA at Pointivo, it's my job to hire engineers and bring them into our organization. Here are some of the questions I like to ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  General intro questions
&lt;/h2&gt;

&lt;p&gt;These are questions that you might ask of any new hire, but I've heard so many bad questions in interviews, that I like to keep these fairly simple and straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you tell us a bit about yourself and your career so far?
&lt;/h3&gt;

&lt;p&gt;I like to allow candidates to introduce themselves at the beginning of interviews, as it can be an opportunity for them to tell their story, explain why they're looking to join our team, or showcase any particular research they've done into our company or industry.&lt;/p&gt;

&lt;p&gt;What I'm looking for here is honesty, and ideally a sense of personal directionality. I want to get the sense that this candidate is trying to move forward in their career and takes their work seriously. It's not a dealbreaker if this doesn't come across, as I've had my own periods of career drift in my life, and some folks simply aren't great at telling their story - but I'm looking for any clues here that will help me understand if this person will align with the role I'm hiring for.&lt;/p&gt;

&lt;h3&gt;
  
  
  What has you looking for a new job at this time?
&lt;/h3&gt;

&lt;p&gt;This is usually my second question, and I'm trying to determine if the candidate is looking to change their career path, has had some undesirable work situation, or perhaps isn't doing well in their current role. Again, no specific dealbreakers here, but I can often tell a lot about a person's current relationship to their work life from how they answer this question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions about general testing concepts
&lt;/h2&gt;

&lt;p&gt;These questions are more specific to the work of a QA engineer or SDET.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is testing? What is testing NOT?
&lt;/h3&gt;

&lt;p&gt;This is a very open-ended question, but it can lead to some interesting answers. Really, what I would like to hear from a candidate is some understanding of &lt;em&gt;test effectiveness&lt;/em&gt;, meaning that they write and execute tests that deliver real value in knowing the truth of a system. We're trying to avoid tests that only provide surface coverage without depth. &lt;/p&gt;

&lt;h3&gt;
  
  
  Can you talk about why testing is important? What are the benefits of testing?
&lt;/h3&gt;

&lt;p&gt;Things like providing confidence in delivery for the Dev team, ensuring product quality, decreasing the loop time between development and feedback, or improving against other business-level KPIs are all good things to hear in a response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you describe and give me your thoughts on The Testing Pyramid?
&lt;/h3&gt;

&lt;p&gt;Here, I'm really just looking for familiarity with some of the basic concepts we use as QA engineers. I want to know that the candidate understands that all work environments will be a blend of unit, integration, and e2e tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the basic types of tests? (Open-ended)
&lt;/h3&gt;

&lt;p&gt;In addition to the broad categories described by the Testing Pyramid, I would like to hear a candidate talk about the differences between functional, UI, security, smoke, and other types of tests. There is less of an officially defined list of these types, so this is a good way to learn what categories the candidate has experience with and how they think about organizing tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  What can you tell me about software development lifecyles (SDLC) you've experienced in the past? What do you think works and what doesn't?
&lt;/h3&gt;

&lt;p&gt;Here, I'm looking to see if the candidate has experience with the basic concepts of Agile, and if they've worked in a scrum environment before. It's okay if they haven't, but it's usually an advantage if they have.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the main QA and test apps/platforms are and what do they do...
&lt;/h3&gt;

&lt;p&gt;Zephyr, TestRail, Qase, Selenium, Playwright, Appium, etc. I usually don't care what systems a person has worked with in the past, but I might want to hear their opinions about what they liked or didn't like. If someone really hates a tool that we use, that might be an issue for them as a member of the team.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is test automation and why is it important? What is your experience in test automation? What is your favorite test automation framework? What is your favorite feature of that framework?
&lt;/h3&gt;

&lt;p&gt;Again, here I mostly just want to find out what prior experiences a person has had, and determine if there's going to be any opportunities or conflicts for them if they come on board the team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Talk about how you approach flexibility in your testing efforts. What would you do if you needed to get a release out tomorrow and none of your regression testing was done?
&lt;/h3&gt;

&lt;p&gt;Sometimes we have to face unrealistic deadlines, and I want to know how someone will respond to pressure and a ticking clock. I'd like to hear about how they would prioritize their testing efforts, and how they would communicate to management about their feelings of readiness for a release. I also want to know that if they feel that a release is unsafe, that they're willing to throw up a red flag and inform the rest of their team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Hopefully there will be some value in this post, both for hiring managers looking to screen candidates, and for candidates preparing for a job interview. These questions are derived from my own personal experience on both sides of interviews.&lt;/p&gt;

&lt;p&gt;Before going into an interview, some research in advance is important, for both sides. If you are hiring someone, make sure you've taken the time to look over their resume, read over their LinkedIn profile, and if they have a personal site or blog, taken some time to get as familiar with them as you can. If you are going in for an interview, make sure you've read over the company's website, are familiar with what they do, and can at least bring in some guesses about the challenges they face.&lt;/p&gt;

&lt;p&gt;Lastly, it's important to remember to approach the process with kindness. Hiring is critically important to the ongoing health of your organization, and a person's work life is critically important to their overall well-being and life satisfaction. Approach the process with kindness, and even if you can tell that a person won't be a good match for a role, try to make the interview process worth their time and give them feedback or exposure to concepts that will help them in future. If you're a candidate and you get the sense that the company isn't for you, use the interview as an opportunity to learn more about what you're looking for or what you want to avoid in a workplace. Remember that we're all just people, trying to get our work done, trying to find the other people we want to work alongside.&lt;/p&gt;

&lt;p&gt;My thanks to everyone who provided ideas for this post by commenting on &lt;a href="https://www.linkedin.com/feed/update/urn%3Ali%3Aactivity%3A7150722218749042688/" rel="noopener noreferrer"&gt;my LinkedIn post&lt;/a&gt; asking for suggestions.&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>testing</category>
      <category>career</category>
    </item>
    <item>
      <title>How to break out of .within() scope in Cypress</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Thu, 18 Jul 2024 20:20:47 +0000</pubDate>
      <link>https://dev.to/samelawrence/how-to-break-out-of-within-scope-in-cypress-4gm3</link>
      <guid>https://dev.to/samelawrence/how-to-break-out-of-within-scope-in-cypress-4gm3</guid>
      <description>&lt;p&gt;I am a huge fan of the Cypress method &lt;code&gt;.within()&lt;/code&gt; for scoping commands to within a specific UI section. However, there may be times when you will want to escape out of this scope and then return to it and carry on with additional testing. Some examples I can think of are when a tooltip might appear over an element on hover, but be scoped outside of the related container in the DOM layout, or if you want to pick up a piece of data from a sibling element before carrying on with the test logic that you do want to be restricted in DOM scope.&lt;/p&gt;

&lt;p&gt;I didn't know how to do this until recently, when such an instance came up, and I found &lt;a href="https://stackoverflow.com/questions/65928822/cypress-how-to-temporarily-escape-from-a-cy-within" rel="noopener noreferrer"&gt;this StackOverflow thread&lt;/a&gt; with the answer. I'm sharing it here as a blog post in case it helps someone else. All credit to &lt;a href="https://stackoverflow.com/users/4716245/richard-matsen" rel="noopener noreferrer"&gt;Richard Matsen&lt;/a&gt; whose code I am stealing here:&lt;/p&gt;

&lt;p&gt;"&lt;code&gt;cy.document().its('body')&lt;/code&gt; will give you a subject that is outside the &lt;code&gt;.within()&lt;/code&gt;, and it seems to go back to inner scope after (still within callback)."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.get('body').find('div.without');  // checking this query first (outer scope)

cy.get('div.myform').within(() =&amp;gt; {

  cy.contains('text within');                      // inner scope

  cy.document().its('body').find('div.without');   // outer scope

  cy.contains('text within');                      // inner scope
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are often scenarios where you can avoid &lt;em&gt;needing&lt;/em&gt; to do this, but for the cases where it's unavoidable, this is a great trick to have up your sleeve.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Three optional styles for UI assertions in Cypress</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Mon, 15 Jul 2024 21:05:46 +0000</pubDate>
      <link>https://dev.to/samelawrence/three-optional-styles-for-ui-assertions-in-cypress-54ab</link>
      <guid>https://dev.to/samelawrence/three-optional-styles-for-ui-assertions-in-cypress-54ab</guid>
      <description>&lt;h3&gt;
  
  
  .contains()
&lt;/h3&gt;

&lt;p&gt;Often, I just want to scan over a UI in Cypress and make sure that a set of text labels are present. It's typically been my habit to style these sorts of tests like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;element.class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Element text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I love the simplicity of &lt;code&gt;cy.contains()&lt;/code&gt;, and the log output of this command will show what text was queried for, but not in the clearest, most visible way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5spkeqcrsisrlr101dkb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5spkeqcrsisrlr101dkb.jpg" alt="Cypress log output using cy.contains()" width="648" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .should()
&lt;/h3&gt;

&lt;p&gt;After a recent code review, I noticed a team-mate styling a similar query like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;element.class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contain.text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Element text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a bit of thought, I realized that this would make for much better output in the Cypress runner log. Here's a screenshot where you can see that the expected text is now highlighted and easier to read. This makes debugging a much simpler process when we get feedback about what text the query was looking for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9merfrh7w4ez6z6kn3wy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9merfrh7w4ez6z6kn3wy.jpg" alt="Cypress log output showing an assertion with .should()" width="644" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  expect()
&lt;/h3&gt;

&lt;p&gt;However, we can go even further and have the Cypress runner log tell us both which string was expected &lt;em&gt;and&lt;/em&gt; what was actually found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;element.class&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Element text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this provides the &lt;em&gt;richest&lt;/em&gt; output to the log, showing both what was expected and what was found.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi8vetux3s3ho5rvkfi2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmi8vetux3s3ho5rvkfi2.jpg" alt="Cypress log output showing an assertion with expect()" width="648" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This style is certainly more verbose, but the additional clarity in log output may make it worth your time. Having consistent style in a codebase can be valuable, but I think it's ok to mix all these various approaches together as long as your focus is on &lt;em&gt;test effectiveness&lt;/em&gt;. Hopefully this article gets you thinking about how you might want clearer logging in certain situations, and how to change up your code style based on your situational needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  addendum
&lt;/h3&gt;

&lt;p&gt;Gleb Bahmutov talks about this in his video "Use Stronger Assertions":&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/HkXx79JE2nU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;You can see that he opts for the second style, using a &lt;code&gt;.should()&lt;/code&gt; assertion to highlight just the expected text in the log. I think this is actually the best style for most use cases, but it can be helpful to lean on richer logging at times, especially when debugging a test as it's being written or modified.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>3 nuggets of advice for mid-level engineers who don't want the management track</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Mon, 29 Apr 2024 02:47:54 +0000</pubDate>
      <link>https://dev.to/samelawrence/3-nuggets-of-advice-for-mid-level-qa-engineers-who-dont-want-the-management-track-40j4</link>
      <guid>https://dev.to/samelawrence/3-nuggets-of-advice-for-mid-level-qa-engineers-who-dont-want-the-management-track-40j4</guid>
      <description>&lt;h3&gt;
  
  
  The Setup
&lt;/h3&gt;

&lt;p&gt;I was recently having a conversation with another QA Engineer who is seeking greater clarity for their career path ahead, and I wanted to share some notes from our discussion in case they are helpful to anyone else.&lt;/p&gt;

&lt;p&gt;This person works in both manual and automated testing, but really prefers the automation side and is even open to moving into a full developer role at some point in the future. They said, no matter what, they wanted to remain in a technical role for the next several years, but didn't have any interest in management or team leadership. I understood them to be asking me for advice on how they could progress through a mid-level career into a more senior position without having to side-step into a management track. It's true that being a lead isn't the same as being an individual contributor, and that shift in responsibility isn't for everyone.&lt;/p&gt;

&lt;p&gt;The advice I gave them was off the cuff, and I can already think of better things I wish I'd said, but I'll share here what I told them - a slice of the sorts of conversations we should all be having with each other to help each other grow and manifest our career goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read books
&lt;/h3&gt;

&lt;p&gt;Reading is telepathy, it is straight-up telepathy. It allows you to read the thoughts inside another person's head, verbatim. Reading helps us develop language skills, which are critically important to supporting a healthy career, and this is even more true if you work with people who speak a different native language than you. Reading in the native language of others can help you better understand how they think and grasp the nuances of a language you might still be learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Give it a try
&lt;/h3&gt;

&lt;p&gt;Even for an engineer who isn't interested in pursuing a management path, as you seek to rise through mid-level into senior roles, you will still have to take on leadership roles of different sorts. Whether mentoring teammates or having to fend for a touch technical decision - knowing how to lead a meeting or organize others is an invaluable skill. I suggested to my friend that they organize a meetup of other QA Engineers in their area who use the same testing tools, and at least see how the experience of trying to organize something like that is for them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplify your online presence
&lt;/h3&gt;

&lt;p&gt;The person I was talking to has worked with a lot of different tools in their career, and has a good broad range of skills as a result, however the way this looked in their resume and LinkedIn profiles, at least in my opinion, was a bit scattered. I've run into this problem in my own career, trying to highlight everything I knew at least a little about, and ending up looking like I didn't have any focused skills.&lt;/p&gt;

&lt;p&gt;In truth, this is actually the case for a lot of junior engineers, they really don't have a focused set of skills, but inevitably we gravitate toward toolsets and methods, and it can be helpful to identify with your strengths by narrowing down your online persona to a few key areas. Rather than listing every tool they'd ever worked with, I encouraged the person I was talking with to highlight the tools they wanted to work with going forward, and which they felt they were moving toward expertise with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This was a quick, casual conversation held between two engineers, and these answers were not well thought-out, but hopefully by sharing them here, someone else might gain some insight. If you found this useful, let me know &lt;a href="https://twitter.com/samelawrence"&gt;on Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>career</category>
    </item>
    <item>
      <title>How I implement drag-and-drop in my Cypress tests</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Tue, 26 Mar 2024 04:20:19 +0000</pubDate>
      <link>https://dev.to/samelawrence/how-i-implement-drag-and-drop-in-my-cypress-tests-ppg</link>
      <guid>https://dev.to/samelawrence/how-i-implement-drag-and-drop-in-my-cypress-tests-ppg</guid>
      <description>&lt;p&gt;Drag and drop interactions can be one of the more challenging things to get right in Cypress tests. I've used several different methods myself and eventually settled on a pattern which, while dependent on a third-party plugin, has proven reliable and stable for my needs.&lt;/p&gt;

&lt;p&gt;My implementation relies on the &lt;code&gt;cypress-real-events&lt;/code&gt; plugin (&lt;a href="https://www.npmjs.com/package/cypress-real-events"&gt;NPM&lt;/a&gt;), which you can learn more about in my article "&lt;a href="https://dev.to/samelawrence/essential-cypress-plugins-i-cant-live-without-g6b"&gt;Essential Cypress Plugins I can't live without&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;With this plugin installed, I just have a &lt;a href="https://docs.cypress.io/api/cypress-api/custom-commands"&gt;custom command&lt;/a&gt; with the following logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dragAndDrop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dragLocator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dropLocator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cy&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="nx"&gt;dragLocator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;realMouseDown&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;realMouseMove&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;cy&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="nx"&gt;dropLocator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;realMouseMove&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;realMouseUp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because I'm just passing in the &lt;code&gt;dragLocator&lt;/code&gt; and &lt;code&gt;dropLocator&lt;/code&gt; values to &lt;code&gt;cy.get()&lt;/code&gt; commands, I can use IDs, CSS classes, or &lt;code&gt;cy-data&lt;/code&gt; locators, just like I would in my normal test logic.&lt;/p&gt;

&lt;p&gt;Notice that after issuing the &lt;code&gt;.realMouseDown()&lt;/code&gt; command, I move the mouse cursor &lt;code&gt;10px&lt;/code&gt; before moving to the element I want to target for the &lt;code&gt;.realMouseUp()&lt;/code&gt; event. That is just to give the UI a little "wiggle" to make sure that the element is picked up by the mouse cursor. Under the hood, I'm honestly not sure why this works, but it has improved reliability for me.&lt;/p&gt;

&lt;p&gt;Also note that I then insert a hard &lt;code&gt;200ms&lt;/code&gt; wait. This is normally considered a bad practice, but in this case it's there as an extra guarantee that everything works smoothly. I don't think waiting 1/5th of a second is much of a price to pay for something as complicated as a drag and drop action.&lt;/p&gt;

&lt;p&gt;I hope this helps you use drag and drop in your codebase more effectively, or if you have another method that you prefer, let me know down in the comments. Thanks for reading!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cypress</category>
    </item>
    <item>
      <title>How I would begin a career in software QA</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Mon, 11 Mar 2024 20:24:23 +0000</pubDate>
      <link>https://dev.to/samelawrence/how-i-would-begin-a-career-in-software-qa-83e</link>
      <guid>https://dev.to/samelawrence/how-i-would-begin-a-career-in-software-qa-83e</guid>
      <description>&lt;p&gt;The world of software is vast and broad, but there aren't many obvious entry points for newcomers, unless those people happened to decide they wanted to work in tech before they were 18. Those people got CS degrees, but what about the rest of us? This article assumes that you &lt;em&gt;want&lt;/em&gt; to do technical work in the software industry, probably programming - you may have some self-taught technical skills today, but I will try to make the following thoughts helpful, whether your skills are basic or advanced.&lt;/p&gt;

&lt;p&gt;It turns out that there are several areas where it's possible to get started in the world of IT, but they each come with challenges and roadblocks. Before I landed my first job in QA, I had tried to get started working in tech via sales, consulting, and support. In my opinion, maneuvering out of those departments into something more technical and interesting will depend far too much much on the size of the company, how departments interact, and how much exposure you might get to the real "guts" of the engineering team.&lt;/p&gt;

&lt;p&gt;This essay will specifically focus on the role of a QA Engineer, and my thoughts on how I would try to start working as one if I were beginning today. Whether you think of this role as an SDET, QA Analyst, or QA Engineer - I'm describing someone involved in testing software. This is the area I work in, now as a QA Lead, and I was able to develop my career with no college degree or background in programming as a teenager.&lt;/p&gt;

&lt;p&gt;In contrast to areas like sales, customer support, and design - I believe that getting an entry-level job in QA is only &lt;em&gt;slightly&lt;/em&gt; harder than a completely non-technical role, yet will open up &lt;em&gt;significantly&lt;/em&gt; more opportunity to get working on real programming and other technical work. For that reason, I recommend it as the &lt;strong&gt;best&lt;/strong&gt; place for aspiring technical people to begin working in the software trade.&lt;/p&gt;

&lt;p&gt;Here's Filip Hric sharing his perspective on this:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DaeFdxSYAyg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you're already writing code, I advise you to go straight for test automation skills as part of your toolkit. There are theoretical aspects to QA that you will need to know in order to be a good tester, but test automation really is such an important part of the industry today, and you'll command a much better salary much faster if you can contribute automation. If you &lt;em&gt;can't&lt;/em&gt; code today, I recommend learning the basic of programming as quickly as you can, and try to get a job using manual testing skills.&lt;/p&gt;

&lt;p&gt;Opinions vary on this, but if I were advising someone to get a job as quickly as possible, my personal recommendation would be to learn Cypress. I've used a few different automation tools and the reason I recommend Cypress is just the ease of setup. It's a great tool for beginners because you don't have to know too much to get started. You will need to know some of the basics of Javascript to learn Cypress - so if you're not coding today, start with learning Javascript.&lt;/p&gt;

&lt;p&gt;While I think test automation represents a huge part of the future of testing, some good concepts you will want to take into interviews with you are The Testing Pyramid, and some basic terminology like &lt;em&gt;functional&lt;/em&gt; vs. &lt;em&gt;unit&lt;/em&gt; testing. I think you should also know some terms around typical team structure - know what a UX designer, a Product Manager, and a Project Manager all do, but you shouldn't get asked too much about their work, only about how you would interface with them.&lt;/p&gt;

&lt;p&gt;The best piece of advice I can give is to just get started &lt;em&gt;trying&lt;/em&gt;. That means getting your resume together and firing off applications. Spend some time in LinkedIn each day, as well as job boards and forums. The last time I was on the job hunt, it was brutal and I hear things have only gotten harder. You should expect to hear a lot of No's, but ask for specific feedback after each rejection and you'll get better faster. If you can track your job applications in a spreadsheet or something similar (I used Airtable), it'll help you stay focused on the best opportunities.&lt;/p&gt;

&lt;p&gt;If you do land a job, get started by just doing the work assigned to you, but continue the process of learning in the background and start asking questions of people who have been there longer than you. I wish you all the greatest success in your career, and feel free to reach out &lt;a href="https://twitter.com/samelawrence"&gt;on Twitter&lt;/a&gt; if I can answer any helpful questions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.pexels.com/photo/blue-retractable-pen-574070/"&gt;Cover Photo by Lukas from Pexels&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>testdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Migrating a QA Team's Test Repo from Testrail to Qase</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Mon, 11 Mar 2024 04:24:28 +0000</pubDate>
      <link>https://dev.to/samelawrence/why-we-migrated-from-testrail-to-qase-and-how-we-did-it-4n54</link>
      <guid>https://dev.to/samelawrence/why-we-migrated-from-testrail-to-qase-and-how-we-did-it-4n54</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;TestRail just isn't cutting it these days in my opinion. I've found Report generation to be slow, I've had issues maintaining auth sessions, several portions of the UI are slow or difficult to navigate, and feature development feels slow, held back by an aging tech stack.&lt;/p&gt;

&lt;p&gt;There are many tools available to testing teams for managing test case repositories. Once I knew I wanted to move my team away from TestRail, I took a look at quite a few options. I wanted something modern, under active developement, with attractive pricing and a good UI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tuskr.app/"&gt;Tuskr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.testrail.com/"&gt;TestRail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://qase.io/"&gt;Qase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After comparing features, assessing our needs, and using a few products on trial -- we decided on Qase. It was more affordable for our needs than our existing TestRail account, it included some nice modern features (Dashboards, Test Run Wizard) that we wanted to take advantage of, and it didn't come with too many drawbacks (custom queries are paywalled above our level).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Migration
&lt;/h2&gt;

&lt;p&gt;Qase will advise you to export your data in XML format, and it will accurately import most of your test data quite well. It struggles with some special characters in the Description/Name field, so check over your tests for any garbled names after import.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/xExuFqwg4_k"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;There will be some special fields that don't come over, so you may want to also export your TestRail repository as XLS to do some manual cleanup. In our case, we were using the &lt;code&gt;References&lt;/code&gt; field to link relevant Shortcut story IDs to our tests. We imported the XLS export into Google Sheets and then collaboratively went to work importing data from the &lt;code&gt;References&lt;/code&gt; field into a new custom field in Qase. Sadly, we lost the TestRail feature that allows you to set a baseUrl scheme for these references, allowing one click back to the related ticket, but just storing the numeric IDs as text will work for us moving forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Overall, our team is happy with Qase. We love the more modern-feeling UI, and the product feels like it's under much more active development than TestRail.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>tooling</category>
    </item>
    <item>
      <title>My favorite cy.type() tips and tricks</title>
      <dc:creator>Sam E. Lawrence</dc:creator>
      <pubDate>Fri, 08 Mar 2024 23:00:51 +0000</pubDate>
      <link>https://dev.to/samelawrence/my-favorite-cytype-tips-and-tricks-3166</link>
      <guid>https://dev.to/samelawrence/my-favorite-cytype-tips-and-tricks-3166</guid>
      <description>&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%2Fm92s61mljll0nx5dczt8.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%2Fm92s61mljll0nx5dczt8.png" alt="Image description" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Someone in the &lt;a href="https://discord.com/invite/cypress" rel="noopener noreferrer"&gt;Cypress Discord&lt;/a&gt; faced an issue where &lt;code&gt;cy.type()&lt;/code&gt; wouldn't enter the full desired string in a form field, resulting in only a partial string value showing up in the UI (and their test not working as expected). This has happened to me before, and if you work with Cypress long enough, it'll probably happen to you at least once.&lt;/p&gt;

&lt;p&gt;This tester's easiest fix was just to insert a hard &lt;code&gt;cy.wait()&lt;/code&gt; to ensure that the field was ready for text entry, but we prefer to try to avoid those. There are a few little tricks I use to deal with this issue when it arises, and I use them each in turn depending on the context. Hopefully something here will help you get unstuck if you ever face issues typing text with Cypress.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Here's an example where I'm using all the tricks at once, and I'll break down each one, line by line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;delay&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  cy.get('field')
&lt;/h3&gt;

&lt;p&gt;No real trick here, but I'll emphasize the importance of selecting the correct element, generally an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; - though not always guaranteed.&lt;/p&gt;

&lt;h3&gt;
  
  
  .should('be.visible')
&lt;/h3&gt;

&lt;p&gt;Cypress is much faster than a human. A form field can receive input as soon as it &lt;em&gt;exists&lt;/em&gt; in the DOM, but by waiting until it is &lt;em&gt;visible&lt;/em&gt;, we have a better chance of waiting long enough for the &lt;code&gt;.type()&lt;/code&gt; action to &lt;em&gt;actually&lt;/em&gt; take place and have effects like filling the field. In modern apps, there's a lot more stuff being done by Javascript and it's important to be able to wait for element availability as close as possible to their "ready" state. Waiting for visibility (page has been painted) is the first good nudge toward knowing when that "ready" state occurs.&lt;/p&gt;

&lt;h3&gt;
  
  
  .clear()
&lt;/h3&gt;

&lt;p&gt;Sometimes form fields contain default text that clears based on a &lt;code&gt;click&lt;/code&gt; or &lt;code&gt;focus&lt;/code&gt; action. If the page's Javascript is still hydrating the page, I've seen this break and newly entered text will sometimes &lt;em&gt;append&lt;/em&gt; the placeholder text. It's generally just a good idea to &lt;code&gt;clear&lt;/code&gt; the field, unless of course you actually want to append text (as in a "Notes" field).&lt;/p&gt;

&lt;h3&gt;
  
  
  .type('string', { delay: 0 })
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;{ delay: 0 }&lt;/code&gt; is open to debate. This option enters the full input string as a chunk, rather than by typing each key individually. This is less like a "real user" would type text into a field, but it can lead to more reliable test automation, if you feel comfortable with the trade-off. It's comparable to a user pasting directly into the field.&lt;/p&gt;

&lt;h3&gt;
  
  
  .should('contain', 'string');
&lt;/h3&gt;

&lt;p&gt;It's good to check the state of any elements you modify. This command will let us confirm that the field is in the correct state, and we can move on with the rest of our test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other options
&lt;/h2&gt;

&lt;p&gt;In my example, I assumed that the field would accept direct text entry, however that's not always the case. You might find that you need to use &lt;code&gt;.click()&lt;/code&gt; on the element before you begin typing. You might also want to use &lt;a href="https://docs.cypress.io/api/commands/focus" rel="noopener noreferrer"&gt;.focus()&lt;/a&gt; to set your cursor into the field. I didn't include these in my happy-path example, because this post was really just about the &lt;code&gt;.type()&lt;/code&gt; command.&lt;/p&gt;

&lt;h3&gt;
  
  
  A plugin option
&lt;/h3&gt;

&lt;p&gt;If you're using the &lt;a href="https://github.com/dmtrKovalenko/cypress-real-events?tab=readme-ov-file#cyrealtype" rel="noopener noreferrer"&gt;cypress-real-events&lt;/a&gt; plugin, you might choose to use &lt;code&gt;cy.realType()&lt;/code&gt; in combination with &lt;code&gt;cy.get().focus()&lt;/code&gt;. This command types in each character, just like from a physical keyboard, so this method may be the most "realistic" option, if that is a priority for your testing goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  I hope this helps
&lt;/h3&gt;

&lt;p&gt;If any of these helped you write more reliable, stable tests - let me know on &lt;a href="https://twitter.com/samelawrence" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://mastodon.social/@awesame" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt;, or &lt;a href="https://bsky.app/profile/awesame.bsky.social" rel="noopener noreferrer"&gt;Bluesky&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>cypress</category>
    </item>
  </channel>
</rss>
