{"id":121105,"date":"2024-02-14T15:32:16","date_gmt":"2024-02-14T15:32:16","guid":{"rendered":"https:\/\/showbizztoday.com\/index.php\/2024\/02\/14\/introducing-safetest-a-novel-approach-to-front-end-testing-by-netflix-technology-blog-feb-2024\/"},"modified":"2024-02-14T15:32:16","modified_gmt":"2024-02-14T15:32:16","slug":"introducing-safetest-a-novel-approach-to-front-end-testing-by-netflix-technology-blog-feb-2024","status":"publish","type":"post","link":"https:\/\/showbizztoday.com\/index.php\/2024\/02\/14\/introducing-safetest-a-novel-approach-to-front-end-testing-by-netflix-technology-blog-feb-2024\/","title":{"rendered":"Introducing SafeTest: A Novel Approach to Front End Testing | by Netflix Technology Blog | Feb, 2024"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<div>\n<div class=\"hu hv hw hx hy\">\n<div class=\"speechify-ignore ab co\">\n<div class=\"speechify-ignore bg l\">\n<div class=\"hz ia ib ic id ab\">\n<div>\n<div class=\"ab ie\"><a href=\"https:\/\/netflixtechblog.medium.com\/?source=post_page-----37f9f88c152d--------------------------------\" rel=\"noopener follow\" target=\"_blank\"><\/p>\n<div>\n<div class=\"bl\" aria-hidden=\"false\">\n<div class=\"l if ig bx ih ii\">\n<div class=\"l fi\"><img decoding=\"async\" alt=\"Netflix Technology Blog\" class=\"l fc bx dc dd cw\" src=\"https:\/\/miro.medium.com\/v2\/resize:fill:88:88\/1*BJWRqfSMf9Da9vsXG9EBRQ.jpeg\" width=\"44\" height=\"44\" loading=\"lazy\" data-testid=\"authorPhoto\"\/><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><\/a><a href=\"https:\/\/netflixtechblog.com\/?source=post_page-----37f9f88c152d--------------------------------\" rel=\"noopener  ugc nofollow\" target=\"_blank\"><\/p>\n<div class=\"il ab fi\">\n<div>\n<div class=\"bl\" aria-hidden=\"false\">\n<div class=\"l im in bx ih io\">\n<div class=\"l fi\"><img decoding=\"async\" alt=\"Netflix TechBlog\" class=\"l fc bx bq ip cw\" src=\"https:\/\/miro.medium.com\/v2\/resize:fill:48:48\/1*ty4NvNrGg4ReETxqU2N3Og.png\" width=\"24\" height=\"24\" loading=\"lazy\" data-testid=\"publicationPhoto\"\/><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p id=\"769f\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">by <a class=\"ny ix fd\" href=\"https:\/\/medium.com\/u\/a155da075195?source=post_page-----37f9f88c152d--------------------------------\" rel=\"noopener\" target=\"_blank\">Moshe Kolodny<\/a><\/p>\n<p id=\"3432\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">In this publish, we\u2019re excited to introduce SafeTest, a revolutionary library that provides a contemporary perspective on End-To-End (E2E) assessments for web-based User Interface (UI) purposes.<\/p>\n<p id=\"5648\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">Traditionally, UI assessments have been carried out by both unit testing or integration testing (additionally known as End-To-End (E2E) testing). However, every of those strategies presents a novel trade-off: it&#8217;s a must to select between controlling the take a look at fixture and setup, or controlling the take a look at driver.<\/p>\n<p id=\"11ab\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">For occasion, when utilizing <a class=\"af pc\" href=\"https:\/\/testing-library.com\/docs\/react-testing-library\/intro\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">react-testing-library<\/a>, a unit testing answer, you keep full management over what to render and the way the underlying companies and imports ought to behave. However, you lose the flexibility to work together with an precise web page, which may result in a myriad of ache factors:<\/p>\n<ul class=\"\">\n<li id=\"d50e\" class=\"na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx pd pe pf bj\">Difficulty in interacting with advanced UI components like &lt;Dropdown \/&gt; parts.<\/li>\n<li id=\"f78c\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Inability to check CORS setup or GraphQL calls.<\/li>\n<li id=\"1789\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Lack of visibility into z-index points affecting click-ability of buttons.<\/li>\n<li id=\"25ce\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Complex and unintuitive authoring and debugging of assessments.<\/li>\n<\/ul>\n<p id=\"7c9f\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">Conversely, utilizing integration testing instruments like Cypress or Playwright gives management over the web page, however sacrifices the flexibility to instrument the bootstrapping code for the app. These instruments function by remotely controlling a browser to go to a URL and work together with the web page. This method has its personal set of challenges:<\/p>\n<ul class=\"\">\n<li id=\"90fa\" class=\"na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx pd pe pf bj\">Difficulty in making calls to another API endpoint with out implementing customized community layer API rewrite guidelines.<\/li>\n<li id=\"8108\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Inability to make assertions on spies\/mocks or execute code throughout the app.<\/li>\n<li id=\"bef2\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Testing one thing like darkish mode entails clicking the theme switcher or realizing the localStorage mechanism to override.<\/li>\n<li id=\"3189\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Inability to check segments of the app, for instance if a element is simply seen after clicking a button and ready for a 60 second timer to countdown, the take a look at might want to run these actions and shall be no less than a minute lengthy.<\/li>\n<\/ul>\n<p id=\"6d84\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">Recognizing these challenges, options like E2E Component Testing have emerged, with choices from <a class=\"af pc\" href=\"https:\/\/docs.cypress.io\/guides\/component-testing\/overview\" rel=\"noopener ugc nofollow\" target=\"_blank\">Cypress<\/a> and <a class=\"af pc\" href=\"https:\/\/playwright.dev\/docs\/test-components\" rel=\"noopener ugc nofollow\" target=\"_blank\">Playwright<\/a>. While these instruments try to rectify the shortcomings of conventional integration testing strategies, they produce other limitations on account of their structure. They begin a dev server with bootstrapping code to load the element and\/or setup code you need, which limits their skill to deal with advanced enterprise purposes that may have OAuth or a fancy construct pipeline. Moreover, updating TypeScript utilization might break your assessments till the Cypress\/Playwright group updates their runner.<\/p>\n<p id=\"7bcb\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">SafeTest goals to handle these points with a novel method to UI testing. The important concept is to have a <a class=\"af pc\" href=\"https:\/\/www.npmjs.com\/package\/safetest#bootstrapping-your-application\" rel=\"noopener ugc nofollow\" target=\"_blank\">snippet of code in our utility bootstrapping stage that injects hooks to run our assessments<\/a> (see the <a class=\"af pc\" href=\"https:\/\/www.npmjs.com\/package\/safetest#how-safetest-works\" rel=\"noopener ugc nofollow\" target=\"_blank\">How Safetest Works<\/a> sections for more information on what that is doing). <strong class=\"nc gu\">Note that how this works has no measurable influence on the common utilization of your app since SafeTest leverages lazy loading to dynamically load the assessments solely when operating the assessments (within the README instance, the assessments aren\u2019t within the manufacturing bundle in any respect).<\/strong> Once that\u2019s in place, we are able to use Playwright to run common assessments, thereby attaining the best browser management we wish for our assessments.<\/p>\n<p id=\"564d\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">This method additionally unlocks some thrilling options:<\/p>\n<ul class=\"\">\n<li id=\"1ba4\" class=\"na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx pd pe pf bj\">Deep linking to a selected take a look at while not having to run a node take a look at server.<\/li>\n<li id=\"4596\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Two-way communication between the browser and take a look at (node) context.<\/li>\n<li id=\"e8c3\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Access to all of the DX options that include Playwright (excluding those that include @playwright\/take a look at).<\/li>\n<li id=\"2d40\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Video recording of assessments, hint viewing, and pause web page performance for attempting out completely different web page selectors\/actions.<\/li>\n<li id=\"8881\" class=\"na nb gt nc b nd pg nf ng nh ph nj nk nl pi nn no np pj nr ns nt pk nv nw nx pd pe pf bj\">Ability to make assertions on spies within the browser in node, matching snapshot of the decision throughout the browser.<\/li>\n<\/ul>\n<p id=\"0a0a\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">SafeTest is designed to really feel acquainted to anybody who has carried out UI assessments earlier than, because it leverages the very best elements of present options. Here\u2019s an instance of easy methods to take a look at a whole utility:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"f3f5\" class=\"pu oa gt pr b bf pv pw l px py\">import { describe, it, count on } from 'safetest\/jest';<br\/>import { render } from 'safetest\/react';<p>describe('my app', () =&gt; {<br\/>it('hundreds the primary web page', async () =&gt; {<br\/>const { web page } = await render();<\/p><p>await count on(web page.getByText('Welcome to the app')).toBeVisible();<br\/>count on(await web page.screenshot()).toMatchImageSnapshot();<br\/>});<br\/>});<\/p><\/span><\/pre>\n<p id=\"645d\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">We can simply as simply take a look at a selected element<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"a79b\" class=\"pu oa gt pr b bf pv pw l px py\">import { describe, it, count on, browserMock } from 'safetest\/jest';<br\/>import { render } from 'safetest\/react';<p>describe('Header element', () =&gt; {<br\/>it('has a traditional mode', async () =&gt; {<br\/>const { web page } = await render(&lt;Header \/&gt;);<\/p><p>await count on(web page.getByText('Admin')).not.toBeVisible();<br\/>});<\/p><p>it('has an admin mode', async () =&gt; {<br\/>const { web page } = await render(&lt;Header admin={true} \/&gt;);<\/p><p>await count on(web page.getByText('Admin')).toBeVisible();<br\/>});<\/p><p>it('calls the logout handler when signing out', async () =&gt; {<br\/>const spy = browserMock.fn();<br\/>const { web page } = await render(&lt;Header handleLogout={fn} \/&gt;);<\/p><p>await web page.getByText('logout').click on();<br\/>count on(await spy).toHaveBeenCalledWith();<br\/>});<br\/>});<\/p><\/span><\/pre>\n<p id=\"0b57\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">SafeTest makes use of React Context to permit for worth overrides throughout assessments. For an instance of how this works, let\u2019s assume we&#8217;ve a fetchPeople perform utilized in a element:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"36b1\" class=\"pu oa gt pr b bf pv pw l px py\">import { useAsync } from 'react-use';<br\/>import { fetchPerson } from '.\/api\/individual';<p>export const People: React.FC = () =&gt; {<br\/>const { knowledge: individuals, loading, error } = useAsync(fetchPeople);<\/p><p>if (loading) return &lt;Loader \/&gt;;<br\/>if (error) return &lt;ErrorWeb page error={error} \/&gt;;<br\/>return &lt;Table knowledge={knowledge} rows=[...] \/&gt;;<br\/>}<\/p><\/span><\/pre>\n<p id=\"3830\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">We can modify the People element to make use of an Override:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"fd00\" class=\"pu oa gt pr b bf pv pw l px py\"> import { fetchPerson } from '.\/api\/individual';<br\/>+import { createOverride } from 'safetest\/react';<p>+const FetchPerson = createOverride(fetchPerson);<\/p><p>export const People: React.FC = () =&gt; {<br\/>+  const fetchPeople = FetchPerson.useValue();<br\/>const { knowledge: individuals, loading, error } = useAsync(fetchPeople);<\/p><p>if (loading) return &lt;Loader \/&gt;;<br\/>if (error) return &lt;ErrorWeb page error={error} \/&gt;;<br\/>return &lt;Table knowledge={knowledge} rows=[...] \/&gt;;<br\/>}<\/p><\/span><\/pre>\n<p id=\"7f56\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">Now, in our take a look at, we are able to override the response for this name:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"9be7\" class=\"pu oa gt pr b bf pv pw l px py\">const pending = new Promise(r =&gt; { \/* Do nothing *\/ });<br\/>const resolved = [{name: 'Foo', age: 23], {title: 'Bar', age: 32]}];<br\/>const error = new Error('Whoops');<p>describe('People', () =&gt; {<br\/>it('has a loading state', async () =&gt; {<br\/>const { web page } = await render(<br\/>&lt;FetchPerson.Override with={() =&gt; () =&gt; pending}&gt;<br\/>&lt;People \/&gt;<br\/>&lt;\/FetchPerson.Override&gt;<br\/>);<\/p><p>await count on(web page.getByText('Loading')).toBeVisible();<br\/>});<\/p><p>it('has a loaded state', async () =&gt; {<br\/>const { web page } = await render(<br\/>&lt;FetchPerson.Override with={() =&gt; async () =&gt; resolved}&gt;<br\/>&lt;People \/&gt;<br\/>&lt;\/FetchPerson.Override&gt;<br\/>);<\/p><p>await count on(web page.getByText('User: Foo, title: 23')).toBeVisible();<br\/>});<\/p><p>it('has an error state', async () =&gt; {<br\/>const { web page } = await render(<br\/>&lt;FetchPerson.Override with={() =&gt; async () =&gt; { throw error }}&gt;<br\/>&lt;People \/&gt;<br\/>&lt;\/FetchPerson.Override&gt;<br\/>);<\/p><p>await count on(web page.getByText('Error getting customers: \"Whoops\"')).toBeVisible();<br\/>});<br\/>});<\/p><\/span><\/pre>\n<p id=\"f8e2\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">The render perform additionally accepts a perform that shall be handed the preliminary app element, permitting for the injection of any desired components anyplace within the app:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"719c\" class=\"pu oa gt pr b bf pv pw l px py\">it('has a individuals loaded state', async () =&gt; {<br\/>const { web page } = await render(app =&gt;<br\/>&lt;FetchPerson.Override with={() =&gt; async () =&gt; resolved}&gt;<br\/>{app}<br\/>&lt;\/FetchPerson.Override&gt;<br\/>);<br\/>await count on(web page.getByText('User: Foo, title: 23')).toBeVisible();<br\/>});<\/span><\/pre>\n<p id=\"49c7\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">With overrides, we are able to write advanced take a look at circumstances akin to making certain a service technique which mixes API requests from <code class=\"cw pz qa qb pr b\">\/foo<\/code>, <code class=\"cw pz qa qb pr b\">\/bar<\/code>, and <code class=\"cw pz qa qb pr b\">\/baz<\/code>, has the right retry mechanism for simply the failed API requests and nonetheless maps the return worth accurately. So if <code class=\"cw pz qa qb pr b\">\/bar<\/code> takes 3 makes an attempt to resolve the tactic will make a complete of 5 API calls.<\/p>\n<p id=\"3a19\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">Overrides aren\u2019t restricted to only API calls (since we are able to use additionally use <code class=\"cw pz qa qb pr b\"><a class=\"af pc\" href=\"https:\/\/playwright.dev\/docs\/api\/class-page#page-route\" rel=\"noopener ugc nofollow\" target=\"_blank\">web page.route<\/a><\/code>), we are able to additionally override particular app degree values like function flags or altering some static worth:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"2bad\" class=\"pu oa gt pr b bf pv pw l px py\">+const UseFlags = createOverride(useFlags);<br\/>export const Admin = () =&gt; {<br\/>+  const useFlags = UseFlags.useValue();<br\/>const { isAdmin } = useFlags();<br\/>if (!isAdmin) return &lt;div&gt;Permission error&lt;\/div&gt;;<br\/>\/\/ ...<br\/>}<p>+const Language = createOverride(navigator.language);<br\/>export const LanguageChanger = () =&gt; {<br\/>-  const language = navigator.language;<br\/>+  const language = Language.useValue();<br\/>return &lt;div&gt;Current language is { language } &lt;\/div&gt;;<br\/>}<\/p><p>describe('Admin', () =&gt; {<br\/>it('works with admin flag', async () =&gt; {<br\/>const { web page } = await render(<br\/>&lt;UseIsAdmin.Override with={oldHook =&gt; {<br\/>const oldFlags = oldHook();<br\/>return { ...oldFlags, isAdmin: true };<br\/>}}&gt;<br\/>&lt;MyComponent \/&gt;<br\/>&lt;\/UseIsAdmin.Override&gt;<br\/>);<\/p><p>await count on(web page.getByText('Permission error')).not.toBeVisible();<br\/>});<br\/>});<\/p><p>describe('Language', () =&gt; {<br\/>it('shows', async () =&gt; {<br\/>const { web page } = await render(<br\/>&lt;Language.Override with={previous =&gt; 'abc'}&gt;<br\/>&lt;MyComponent \/&gt;<br\/>&lt;\/Language.Override&gt;<br\/>);<\/p><p>await count on(web page.getByText('Current language is abc')).toBeVisible();<br\/>});<br\/>});<\/p><\/span><\/pre>\n<p id=\"875d\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">Overrides are a robust function of SafeTest and the examples right here solely scratch the floor. For extra info and examples, consult with the <a class=\"af pc\" href=\"https:\/\/www.npmjs.com\/package\/safetest#overrides\" rel=\"noopener ugc nofollow\" target=\"_blank\">Overrides part<\/a> on the <a class=\"af pc\" href=\"https:\/\/github.com\/kolodny\/safetest\/blob\/main\/README.md\" rel=\"noopener ugc nofollow\" target=\"_blank\">README<\/a>.<\/p>\n<p id=\"9159\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">SafeTest comes out of the field with highly effective reporting capabilities, akin to computerized linking of video replays, Playwright hint viewer, and even <a class=\"af pc\" href=\"https:\/\/safetest-two.vercel.app\/vite-react-ts\/?test_path=.%2FAnother.safetest&amp;test_name=Main2+can+do+many+interactions+fast\" rel=\"noopener ugc nofollow\" target=\"_blank\">deep hyperlink on to the mounted examined element<\/a>. The SafeTest repo <a class=\"af pc\" href=\"https:\/\/github.com\/kolodny\/safetest\/blob\/main\/README.md\" rel=\"noopener ugc nofollow\" target=\"_blank\">README<\/a> hyperlinks to all of the <a class=\"af pc\" href=\"https:\/\/safetest-two.vercel.app\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">instance apps<\/a> in addition to the <a class=\"af pc\" href=\"https:\/\/safetest-two.vercel.app\/report.html#results=vite-react-ts\/artifacts\/results.json&amp;url=vite-react-ts\/\" rel=\"noopener ugc nofollow\" target=\"_blank\">reviews<\/a><\/p>\n<figure class=\"pl pm pn po pp qf qc qd paragraph-image\">\n<div role=\"button\" tabindex=\"0\" class=\"qg qh fi qi bg qj\">\n<div class=\"qc qd qe\"><picture><source srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/format:webp\/1*OFmV3PX7Is8X48-V9ryeig.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\" type=\"image\/webp\"\/><source data-testid=\"og\" srcset=\"https:\/\/miro.medium.com\/v2\/resize:fit:640\/1*OFmV3PX7Is8X48-V9ryeig.png 640w, https:\/\/miro.medium.com\/v2\/resize:fit:720\/1*OFmV3PX7Is8X48-V9ryeig.png 720w, https:\/\/miro.medium.com\/v2\/resize:fit:750\/1*OFmV3PX7Is8X48-V9ryeig.png 750w, https:\/\/miro.medium.com\/v2\/resize:fit:786\/1*OFmV3PX7Is8X48-V9ryeig.png 786w, https:\/\/miro.medium.com\/v2\/resize:fit:828\/1*OFmV3PX7Is8X48-V9ryeig.png 828w, https:\/\/miro.medium.com\/v2\/resize:fit:1100\/1*OFmV3PX7Is8X48-V9ryeig.png 1100w, https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*OFmV3PX7Is8X48-V9ryeig.png 1400w\" sizes=\"(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px\"\/><img alt=\"Image of SafeTest report showing a video of a test run\" class=\"bg mh qk c\" width=\"700\" height=\"565\" loading=\"lazy\"\/><\/picture><\/div>\n<\/div>\n<\/figure>\n<p id=\"b09e\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">Many giant companies want a type of authentication to make use of the app. Typically, navigating to localhost:3000 simply leads to a perpetually loading web page. You must go to a unique port, like localhost:8000, which has a proxy server to examine and\/or inject auth credentials into underlying service calls. This limitation is among the important causes that Cypress\/Playwright Component Tests aren\u2019t appropriate to be used at Netflix.<\/p>\n<p id=\"cff2\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">However, there\u2019s normally a service that may generate take a look at customers whose credentials we are able to use to log in and work together with the applying. This facilitates creating a lightweight wrapper round SafeTest to robotically generate and assume that take a look at consumer. For occasion, right here\u2019s principally how we do it at Netflix:<\/p>\n<pre class=\"pl pm pn po pp pq pr ps bo pt ba bj\"><span id=\"d4d4\" class=\"pu oa gt pr b bf pv pw l px py\">import { setup } from 'safetest\/setup';<br\/>import { createTestUser, addCookies } from 'netflix-test-helper';<p>sort Setup = Parameters&lt;typeof setup&gt;[0] &amp; {<br\/>additionalUserChoices?: UserChoices;<br\/>};<\/p><p>export const setupNetflix = (choices: Setup) =&gt; {<br\/>setup({<br\/>...choices,<br\/>hooks: { beforeNavigate: [async page =&gt; addCookies(page)] },<br\/>});<\/p><p>beforeAll(async () =&gt; {<br\/>createTestUser(choices.additionalUserChoices)<br\/>});<br\/>};<\/p><\/span><\/pre>\n<p id=\"0c05\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">After setting this up, we merely import the above bundle rather than the place we&#8217;d have used safetest\/setup.<\/p>\n<p id=\"e8be\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">While this publish centered on how SafeTest works with React, it\u2019s not restricted to only React. SafeTest additionally works with Vue, Svelte, Angular, and even can run on NextJS or Gatsby. It additionally runs utilizing both Jest or Vitest based mostly on which take a look at runner your scaffolding began you off with. The <a class=\"af pc\" href=\"https:\/\/github.com\/kolodny\/safetest\/tree\/main\/examples\" rel=\"noopener ugc nofollow\" target=\"_blank\">examples folder<\/a> demonstrates easy methods to use SafeTest with completely different tooling combos, and we encourage contributions so as to add extra circumstances.<\/p>\n<p id=\"c359\" class=\"pw-post-body-paragraph na nb gt nc b nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv nw nx gm bj\">At its core, SafeTest is an clever glue for a take a look at runner, a UI library, and a browser runner. Though the most typical utilization at Netflix employs Jest\/React\/Playwright, it\u2019s straightforward so as to add extra adapters for different choices.<\/p>\n<p id=\"1420\" class=\"pw-post-body-paragraph na nb gt nc b nd ox nf ng nh oy nj nk nl oz nn no np pa nr ns nt pb nv nw nx gm bj\">SafeTest is a robust testing framework that\u2019s being adopted inside Netflix. It permits for straightforward authoring of assessments and gives complete reviews when and the way any failures occurred, full with hyperlinks to view a playback video or manually run the take a look at steps to see what broke. We\u2019re excited to see the way it will revolutionize UI testing and stay up for your suggestions and contributions.<\/p>\n<\/div>\n<p>[ad_2]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] by Moshe Kolodny In this publish, we\u2019re excited to introduce SafeTest, a revolutionary library that provides a contemporary perspective on End-To-End (E2E) assessments for web-based User Interface (UI) purposes. Traditionally, UI assessments have been carried out by both unit testing or integration testing (additionally known as End-To-End (E2E) testing). However, every of those strategies [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":121107,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[37],"tags":[],"class_list":{"0":"post-121105","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-netflix"},"_links":{"self":[{"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/posts\/121105","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/comments?post=121105"}],"version-history":[{"count":0,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/posts\/121105\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/media\/121107"}],"wp:attachment":[{"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/media?parent=121105"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/categories?post=121105"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/showbizztoday.com\/index.php\/wp-json\/wp\/v2\/tags?post=121105"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}