This repository has been archived by the owner on Jul 9, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathrss-en.xml
3457 lines (3450 loc) · 802 KB
/
rss-en.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>
web.dev
</title>
<subtitle>
Let's build the future of the web.
</subtitle>
<link href="https://web.dev/feed.xml" rel="self"/>
<link href="https://web.dev"/>
<updated>
2023-08-04T15:10:17Z
</updated>
<id>
https://web.dev/
</id>
<author>
<name>
Google Developers
</name>
</author>
<icon>
https://web.dev/images/social.png
</icon>
<logo>
https://web.dev/images/shared/rss-banner.png
</logo>
<entry>
<title>
New to the web platform in July
</title>
<link href="https://web.dev/web-platform-07-2023/"/>
<updated>
2023-07-31T00:00:00Z
</updated>
<id>
https://web.dev/web-platform-07-2023/
</id>
<content type="text/html" mode="escaped">
<h2 id="stable-browser-releases">Stable browser releases <a class="headline-link" href="https://web.dev/web-platform-07-2023/#stable-browser-releases">#</a></h2>
<p>In July 2023 <a href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/115" rel="noopener">Firefox 115</a> and <a href="https://developer.chrome.com/blog/new-in-chrome-115/" rel="noopener">Chrome 115</a> became stable. This post takes a look at what that means for the web platform.</p>
<aside class="aside flow bg-state-bad-bg color-state-bad-text"><p class="cluster color-state-bad-text"><span class="aside__icon box-block "><svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Error sign"> <path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z"></path> </svg></span><strong>Caution</strong></p><div class=" flow"> We include browser compatibility data pulled from MDN in these posts which may not have been updated yet for very recent browser releases. The post will show the correct information as soon as it appears in the <a href="https://github.com/mdn/browser-compat-data/releases">browser-compat-data release</a>. </div></aside>
<h3 id="multiple-values-for-the-css-display-property">Multiple values for the CSS <code>display</code> property <a class="headline-link" href="https://web.dev/web-platform-07-2023/#multiple-values-for-the-css-display-property">#</a></h3>
<p>Chrome 115 includes multiple values for the CSS <code>display</code> property. This means that <code>display: flex</code> becomes <code>display: block flex</code> and <code>display: block</code> becomes <code>display: block flow</code>. The single values are maintained as legacy keywords, these values are now available in the three major engines.</p>
<div class="wdi-browser-compat">
<span class="wdi-browser-compat__label">Browser support</span>
<ul class="wdi-browser-compat__items">
<li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="chrome">
<span class="visually-hidden">Chrome, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported">
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="firefox">
<span class="visually-hidden">Firefox 70, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
70
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="edge">
<span class="visually-hidden">Edge, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported"><p></p>
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="safari">
<span class="visually-hidden">Safari 15, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
15
</span>
</li><p></p>
</ul>
</div>
<h3 id="scroll-driven-animations">Scroll-driven animations <a class="headline-link" href="https://web.dev/web-platform-07-2023/#scroll-driven-animations">#</a></h3>
<p>Also in Chrome 115 are the <code>ScrollTimeline</code> and <code>ViewTimeline</code> extensions to the Web Animations specification. These enable <a href="https://developer.chrome.com/articles/scroll-driven-animations/" rel="noopener">scroll-driven animations</a> via CSS and JavaScript.</p>
<div class="wdi-browser-compat">
<span class="wdi-browser-compat__label">Browser support</span>
<ul class="wdi-browser-compat__items">
<li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="chrome">
<span class="visually-hidden">Chrome, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported">
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="firefox">
<span class="visually-hidden">Firefox, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported"><p></p>
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="edge">
<span class="visually-hidden">Edge, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported"><p></p>
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="safari">
<span class="visually-hidden">Safari, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported"><p></p>
<p></p></span>
</li><p></p>
</ul>
</div>
<h3 id="privacy-sandbox-apis">Privacy Sandbox APIs <a class="headline-link" href="https://web.dev/web-platform-07-2023/#privacy-sandbox-apis">#</a></h3>
<p>The Privacy Sandbox <a href="https://developer.chrome.com/blog/privacy-sandbox-launch/" rel="noopener">relevance and measurement APIs</a> shipped in Chrome 115. This includes the Topics, Protected Audience, Attribution Reporting, Private Aggregation, Shared Storage, and Fenced Frames APIs.</p>
<p>To understand more about these APIs check out the <a href="https://developer.chrome.com/blog/privacy-sandbox-demos/" rel="noopener">Privacy Sandbox demos</a>.</p>
<h3 id="the-animation-composition-property">The <code>animation-composition</code> property <a class="headline-link" href="https://web.dev/web-platform-07-2023/#the-animation-composition-property">#</a></h3>
<p>Firefox 115 supports the CSS <a href="https://developer.mozilla.org/docs/Web/CSS/animation-composition" rel="noopener"><code>animation-composition</code></a> property. Making <code>animation-composition</code> supported in all three major engines. Learn more in the article <a href="https://developer.chrome.com/articles/css-animation-composition/" rel="noopener">Specify how multiple animation effects should composite with animation-composition</a>.</p>
<div class="wdi-browser-compat">
<span class="wdi-browser-compat__label">Browser support</span>
<ul class="wdi-browser-compat__items">
<li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="chrome">
<span class="visually-hidden">Chrome 112, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
112
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="firefox">
<span class="visually-hidden">Firefox 104, Behind a flag</span>
</span>
<span class="wdi-browser-compat__version" data-compat="flag" title="Behind a flag" aria-label="Behind a flag">
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="edge">
<span class="visually-hidden">Edge 112, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
112
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="safari">
<span class="visually-hidden">Safari 16, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
16
</span>
</li><p></p>
</ul>
<a class="wdi-browser-compat__link" href="https://developer.mozilla.org/docs/Web/CSS/animation-composition#browser_compatibility" target="_blank">Source</a>
</div>
<h3 id="array-methods">Array methods <a class="headline-link" href="https://web.dev/web-platform-07-2023/#array-methods">#</a></h3>
<p>Also reaching interoperability with Firefox 115 are a set of methods for <code>Array</code> and <code>TypedArray</code>. <code>Array.toReversed()</code>, <code>Array.toSorted()</code>, <code>Array.toSpliced()</code>, <code>Array.with()</code>, <code>TypedArrays.toReversed()</code>, <code>TypedArrays.toSorted()</code>, and <code>TypedArrays.with()</code> return a new array with elements that have been shallow copied.</p>
<div class="wdi-browser-compat">
<span class="wdi-browser-compat__label">Browser support</span>
<ul class="wdi-browser-compat__items">
<li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="chrome">
<span class="visually-hidden">Chrome 110, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
110
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="firefox">
<span class="visually-hidden">Firefox, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported">
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="edge">
<span class="visually-hidden">Edge 110, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
110
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="safari">
<span class="visually-hidden">Safari 16, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
16
</span>
</li><p></p>
</ul>
<a class="wdi-browser-compat__link" href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed#browser_compatibility" target="_blank">Source</a>
</div>
<h2 id="beta-browser-releases">Beta browser releases <a class="headline-link" href="https://web.dev/web-platform-07-2023/#beta-browser-releases">#</a></h2>
<p>Beta browser versions give you a preview of things that will be in the next stable version of the browser. It's a great time to test new features, or removals, that could impact your site before the world gets that release. New betas are <a href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/116" rel="noopener">Firefox 116</a> and <a href="https://developer.chrome.com/blog/chrome-116-beta/" rel="noopener">Chrome 116</a>. The <a href="https://developer.apple.com/documentation/safari-release-notes/safari-16_6-release-notes" rel="noopener">Safari 17</a> and <a href="https://developer.apple.com/documentation/safari-release-notes/safari-16_6-release-notes" rel="noopener">Safari 16.6</a> betas are still ongoing. These releases bring many great features to the platform. Check out the release notes for all of the details, here are just a few highlights.</p>
<p>Firefox 116 supports the <a href="https://developer.mozilla.org/docs/Web/API/Audio_Output_Devices_API" rel="noopener">Audio Output Devices API</a> on all platforms except for Android. This API allows web applications to redirect audio output to a permitted Bluetooth headset, speakerphone, or other device, instead of having to use the browser or underlying OS default.</p>
<p>Chrome 116 includes CSS Motion Path allowing any graphical object to be animated it along a path specified by the developer. This allows a number of powerful new transform possibilities, such as positioning using polar coordinates (with the <code>ray()</code> function) rather than the standard rectangular coordinates used by the <code>translate()</code> function, or animating an element along a defined path. This makes it easier to define complex and beautiful 2d spatial transitions. A path can be specified as <code>circle()</code>, <code>ellipse()</code>, <code>rect()</code>, <code>inset()</code>, <code>xywh()</code>, <code>polygon()</code>, <code>ray()</code> and <code>url()</code>.</p>
<p>Also in Chrome 116 is the <a href="https://developer.chrome.com/docs/web-platform/document-picture-in-picture/" rel="noopener">Document Picture-in-Picture API</a>. This enables an always-on-top window that can be populated with arbitrary HTMLElements. This is an expansion upon the existing HTMLVideoElement API that only allows for an HTMLVideoElement to be put into a Picture-in-Picture (PiP) window.</p>
<p><em>Photo by <a href="https://unsplash.com/@ninjason" rel="noopener">Jason Leung</a>.</em></p>
</content>
<author>
<name>
Rachel Andrew
</name>
</author>
</entry>
<entry>
<title>
Adapting typography to user preferences with CSS
</title>
<link href="https://web.dev/adapting-typography-to-user-preferences-with-css/"/>
<updated>
2023-07-27T00:00:00Z
</updated>
<id>
https://web.dev/adapting-typography-to-user-preferences-with-css/
</id>
<content type="text/html" mode="escaped">
<p>Bringing the user into the design process has been an exciting time for users,
designers and developers. Users can land on your experience and seamlessly begin
consuming content, their preferences richly integrated into the design result.</p>
<p>This blog post explores using CSS media queries with a variable font to tailor
the reading experience even further. Font grade and weight can be customized
with <code>font-variation-settings</code>, allowing microtuning given various preferences
and contexts, like a preference for dark mode or high contrast. We can take
these preferences and tailor a variable font for that user experience.</p>
<ul>
<li>Dark mode gets a slightly reduced gradation.</li>
<li>High contrast gets a bolder font.</li>
<li>Low contrast gets a thinner font.</li>
</ul>
<figure data-size="full">
<video autoplay="" controls="" loop="" muted=""> <source src="https://storage.googleapis.com/web-dev-uploads/video/vS06HQ1YTsbMKSFTIPl2iogUQP73/cgGryLwncKVnBUQ8iQOF.mp4" type="video/mp4" /> </video>
<figcaption>
<a href="https://codepen.io/argyleink/pen/mdQrqvj">https://codepen.io/argyleink/pen/mdQrqvj</a>
</figcaption>
</figure>
<p>Follow along to understand each portion of the CSS and variable font that enable
this meaningful moment!</p>
<h2 id="getting-setup">Getting setup <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#getting-setup">#</a></h2>
<p>To help focus on the CSS and font variation setting values, but also give us
something to read and see, here's the markup you can use to preview the work:</p>
<div><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span>Variable font weight based on contrast preference<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><br /><br /><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><br /> Lorem ipsum dolor sit amet consectetur adipisicing elit.<br /> Officia, quod? Quidem, nemo aliquam, magnam rerum distinctio<br /> itaque nisi nam, cupiditate dolorum ad sint. Soluta nemo<br /> labore aliquid ex, dicta corporis.<br /><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span></code></pre>
</div><p>Without adding any CSS, the font size is already adaptive to user preferences.
Here's a video from another demo showing how setting <code>font-size</code> in pixels will
squash any user preferences, and why you should set your font size in rems:</p>
<p><video autoplay="" controls="" loop="" muted=""> <source src="https://storage.googleapis.com/web-dev-uploads/video/vS06HQ1YTsbMKSFTIPl2iogUQP73/8mxSKsYmv6K7zoqDor0F.mp4" type="video/mp4" /> </video></p>
<p>Lastly, to center and support the demo, a little CSS:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo.support</span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">display</span><span class="token punctuation">:</span> grid<span class="token punctuation">;</span><br /> <span class="token property">place-content</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span><br /> <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--size-5<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token property">gap</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--size-5<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token selector">h1</span> <span class="token punctuation">{</span><br /> <span class="token property">text-wrap</span><span class="token punctuation">:</span> balance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><img alt="A screenshot preview of the demo so far, in both dark and light themes." decoding="async" height="327" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format" srcset="https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/upVZBhu250ETgmczvTeh.png?auto=format&w=1600 1600w" width="800" />
<p>This demo setup lets you begin testing and implementing this neat typography UX
feature.</p>
<h2 id="loading-the-roboto-flex-variable-font">Loading the Roboto Flex variable font <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#loading-the-roboto-flex-variable-font">#</a></h2>
<p>The adaptive strategy depends on a variable font with meaningful axes for
customization, specifically you need <code>GRAD</code> and <code>wght</code>. The target adaptive user
preferences in this article are for color scheme and contrast, both of which
will tailor these axes to match the user's desired preference.</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> A variable font is not required to achieve this user experience that matches preferences, however, using one achieves the effect without loading multiple weights or versions of a font. See <a href="https://codepen.io/web-dot-dev/pen/zYMmevQ">this demo</a> for an example of this UX without a dependency on a variable font. </div></aside>
<p>Load the variable font using the <code>@font-face</code> API of CSS:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@font-face</span></span> <span class="token punctuation">{</span><br /> <span class="token property">font-family</span><span class="token punctuation">:</span> <span class="token string">"Roboto Flex"</span><span class="token punctuation">;</span><br /> <span class="token property">src</span><span class="token punctuation">:</span> <span class="token url"><span class="token function">url</span><span class="token punctuation">(</span><span class="token string url">'https://assets.codepen.io/2585/RobotoFlex'</span><span class="token punctuation">)</span></span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'truetype'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>Next, apply the font to some content. The following CSS applies it to
everything:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo.support</span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">font-family</span><span class="token punctuation">:</span> Roboto Flex<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><img alt="A screenshot preview of the demo so far, with the font now in Roboto Flex in both dark and light themes." decoding="async" height="327" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format" srcset="https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/vS06HQ1YTsbMKSFTIPl2iogUQP73/hfdJqPvkp2v8HvsH7x4o.png?auto=format&w=1600 1600w" width="800" />
<h2 id="css-custom-properties-and-media-queries-for-the-win">CSS custom properties and media queries for the win <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#css-custom-properties-and-media-queries-for-the-win">#</a></h2>
<p>With the font loaded, you can query for user preferences and adapt the variable
font settings to match.</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> If you need a review on some of these styles, check out the <a href="https://web.dev/learn/css/">Learn CSS</a> module on <a href="https://web.dev/learn/design/media-queries/">media queries</a> or this post on <a href="https://web.dev/building-a-color-scheme/">building an adaptive color scheme with custom properties</a>. </div></aside>
<h3 id="settings-when-theres-no-preferences-default">Settings when there's no preferences (default) <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#settings-when-theres-no-preferences-default">#</a></h3>
<p>The following initial styles will be the default styles, or another way to look
at it, the styles for users without any preferences.</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 400<span class="token punctuation">;</span><br /> <span class="token property">--base-grade</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span><br /><br /> <span class="token property">font-variation-settings</span><span class="token punctuation">:</span><br /> <span class="token string">"wght"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-weight<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token string">"GRAD"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-grade<span class="token punctuation">)</span><br /> <span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><h3 id="settings-when-the-preference-is-for-high-contrast">Settings when the preference is for high contrast <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#settings-when-the-preference-is-for-high-contrast">#</a></h3>
<p>For users who have indicated a preference for high contrast in their system
settings, increase the <code>--base-weight</code> value from <code>400</code> to <code>700</code>:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> more<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 700<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>Now there's more contrast while reading.</p>
<h3 id="settings-when-the-preference-is-for-low-contrast">Settings when the preference is for low contrast <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#settings-when-the-preference-is-for-low-contrast">#</a></h3>
<p>For users who have indicated a preference for low contrast in their system
settings, decrease the <code>--base-weight</code> value from <code>400</code> to <code>200</code>:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> less<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 200<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>Now there's less contrast while reading.</p>
<h3 id="settings-when-the-preference-is-for-dark-mode">Settings when the preference is for dark mode <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#settings-when-the-preference-is-for-dark-mode">#</a></h3>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-color-scheme</span><span class="token punctuation">:</span> dark<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-grade</span><span class="token punctuation">:</span> -25<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>Now the perceptual differences of light on dark vs dark on light have been
accounted for.</p>
<h3 id="all-together-now">All together now <a class="headline-link" href="https://web.dev/adapting-typography-to-user-preferences-with-css/#all-together-now">#</a></h3>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 400<span class="token punctuation">;</span><br /> <span class="token property">--base-grade</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span><br /><br /> <span class="token property">font-variation-settings</span><span class="token punctuation">:</span><br /> <span class="token string">"wght"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-weight<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token string">"GRAD"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-grade<span class="token punctuation">)</span><br /> <span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> more<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 700<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> less<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 200<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-color-scheme</span><span class="token punctuation">:</span> dark<span class="token punctuation">)</span></span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-grade</span><span class="token punctuation">:</span> -25<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>Or, for fun, all together with <a href="https://developer.chrome.com/articles/css-nesting/" rel="noopener">CSS nesting</a>:</p>
<div><pre class="language-css"><code class="language-css"><span class="token atrule"><span class="token rule">@layer</span> demo</span> <span class="token punctuation">{</span><br /> <span class="token selector">body</span> <span class="token punctuation">{</span><br /> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 400<span class="token punctuation">;</span><br /> <span class="token property">--base-grade</span><span class="token punctuation">:</span> 0<span class="token punctuation">;</span><br /><br /> <span class="token property">font-variation-settings</span><span class="token punctuation">:</span><br /> <span class="token string">"wght"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-weight<span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token string">"GRAD"</span> <span class="token function">var</span><span class="token punctuation">(</span>--base-grade<span class="token punctuation">)</span><br /> <span class="token punctuation">;</span><br /><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> more<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 700 <span class="token punctuation">}</span><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-contrast</span><span class="token punctuation">:</span> less<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token property">--base-weight</span><span class="token punctuation">:</span> 200 <span class="token punctuation">}</span><br /> <span class="token atrule"><span class="token rule">@media</span> <span class="token punctuation">(</span><span class="token property">prefers-color-scheme</span><span class="token punctuation">:</span> dark<span class="token punctuation">)</span></span> <span class="token punctuation">{</span> <span class="token property">--base-grade</span><span class="token punctuation">:</span> -25 <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
</div><p>The result is a reading experience that adapts the font to match the user's
preferences. Full source code is available below in the Codepen.</p>
<div class="codepen-embed-wrap" style="height: 500px; width: 100%">
<iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi;" loading="lazy" src="https://codepen.io/web-dot-dev/embed/rNQZMzo?height=500&theme-id=light&default-tab=result&editable=true" style="height: 100%; width: 100%; border: 0;" title="Pen rNQZMzo by web-dot-dev on Codepen">See the Pen <a href="https://codepen.io/web-dot-dev/embed/rNQZMzo">Pen rNQZMzo by web-dot-dev on Codepen</a></iframe></div>
</content>
<author>
<name>
Adam Argyle
</name>
</author>
</entry>
<entry>
<title>
Designing the user experience of passkeys on Google accounts
</title>
<link href="https://web.dev/passkey-google-ux/"/>
<updated>
2023-07-26T00:00:00Z
</updated>
<id>
https://web.dev/passkey-google-ux/
</id>
<content type="text/html" mode="escaped">
<p>Passkeys are a simple and <a href="https://security.googleblog.com/2023/05/so-long-passwords-thanks-for-all-phish.html" rel="noopener">secure cross-device authentication
technology</a>
that enables creating online accounts and signing in to them without entering a
password. To log in to an account, users are simply shown a prompt to to use the
screen lock on their device, such as touching the fingerprint sensor.</p>
<p>Google has been working with the FIDO Alliance for years, alongside Apple and
Microsoft, to bring passkeys to the world. In 2022 we rolled out platform
support for passkeys so that
<a href="https://android-developers.googleblog.com/2022/10/bringing-passkeys-to-android-and-chrome.html" rel="noopener">Android</a>
and
<a href="https://blog.chromium.org/2022/12/introducing-passkeys-in-chrome.html" rel="noopener">Chrome</a>
users can seamlessly sign in to apps and websites across all their devices. In
May 2023, we enabled signing in to <a href="https://blog.google/technology/safety-security/the-beginning-of-the-end-of-the-password/" rel="noopener">Google Accounts with
passkeys</a>,
bringing the security and convenience of passkeys to our users.</p>
<p>Google is in a unique position, as we are both working on the infrastructure for
passkeys and are one of the largest services using them. We are rolling out
passkeys for Google Accounts carefully and deliberately, so we can measure the
results and use that feedback to continue to improve the passkey infrastructure
and the Google account experience.</p>
<h2 id="transitioning-users-to-passkeys">Transitioning users to passkeys <a class="headline-link" href="https://web.dev/passkey-google-ux/#transitioning-users-to-passkeys">#</a></h2>
<p>Passwords have been the standard sign-in method since the advent of personalized
online experiences. How do we introduce the passwordless experience of passkeys?</p>
<p>Research indicates that when it comes to authentication, users value the
convenience the most. They want a smooth and fast transition to the real
experience, which only comes after signing in.</p>
<p>Still, the transition to passkeys requires changing muscle memory and users need
to be convinced it's worth making a switch.</p>
<p>The user experience of passkeys for <a href="http://google.com/" rel="noopener">Google.com</a> has been
strategically designed to emphasize two principles at every step of the
authentication process: ease of use and security.</p>
<h3 id="leading-with-convenience">Leading with convenience <a class="headline-link" href="https://web.dev/passkey-google-ux/#leading-with-convenience">#</a></h3>
<figure>
<img alt="For most users, this will be the first time they see passkeys" decoding="async" height="600" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/UI5EioUkpDiMtUAdARnw.png?auto=format&w=1600 1600w" width="800" />
<figcaption>For most users, this will be the first time they see passkeys.</figcaption>
</figure>
<p>The first passkey screen users see is light and easy-to-digest. The header is
focusing on the user benefit, saying &quot;Simplify your sign in.&quot;</p>
<p>The body copy explains &quot;With passkeys you can now use your fingerprint, face or
screen lock to verify it's really you&quot;.</p>
<p>The illustration is intended to ground the message in the value proposition made
by the page. The large blue primary action invites the user to proceed. &quot;Not
now&quot; is included as a secondary action to allow users to choose whether or not
to opt in at this time, leaving the user in control. And &quot;Learn more&quot; is offered
for the most curious users who would like to understand passkeys better before
proceeding.</p>
<p>We explored many iterations of the pages used to introduce users to passkeys
during sign in. This included trying content that emphasized the security,
technology, and other aspects of passkeys—yet convenience was really what
resonated most. Google's content strategy, illustration, and interaction design
demonstrates this core principle for our implementation of passkeys.</p>
<h3 id="associating-the-term-passkeys-with-familiar-security-experiences">Associating the term &quot;passkeys&quot; with familiar security experiences <a class="headline-link" href="https://web.dev/passkey-google-ux/#associating-the-term-passkeys-with-familiar-security-experiences">#</a></h3>
<p>Passkeys are a new term for most users so we are intentionally gently exposing
the users to the term to build familiarity. Guided by internal research, we are
strategically associating passkeys with security.</p>
<p>The word &quot;passkey&quot; is included throughout the sign-in flow in the less-prominent
body copy position. It's consistently nestled amongst the familiar security
experiences that enable passkey use: fingerprint, face scan, or other device
screen lock.</p>
<p>Our research has shown that many users associate biometrics with security. While
passkeys don't require biometrics (a passkey can be used with a device PIN, for
example), we are leaning into the association of passkeys with biometrics to
boost user perception of passkeys' security benefits.</p>
<p>The additional content behind the &quot;Learn more&quot; has lots of valuable information
for users, including reassurance for users that their sensitive, biometric data
stays on their personal device and is never stored or shared when creating or
using passkeys. We took this approach because most users found the convenience
aspect of passkeys appealing, but only a few took into account the biometric
element during testing.</p>
<h3 id="introducing-passkeys-when-its-relevant-to-the-user">Introducing passkeys when it's relevant to the user <a class="headline-link" href="https://web.dev/passkey-google-ux/#introducing-passkeys-when-its-relevant-to-the-user">#</a></h3>
<p>Google's heuristics carefully determine who will see the introductory screen.
Some of the factors are whether a user has two-step verification enabled and
whether they access that account regularly from the same device.</p>
<p>Users who are most likely to succeed with passkeys are selected first, and over
time more users will be introduced (though, anyone can get started at
<a href="http://g.co/passkeys" rel="noopener">g.co/passkeys</a> today).</p>
<p>Select users are prompted to create a passkey after signing in with a username
and password. There are a few reasons we chose this point in the user journey:</p>
<ul>
<li>The user has just signed in, they're aware of their credentials and second
step.</li>
<li>We are confident that the user is on their device–they just signed in, so it's
unlikely they walked away or put their device down.</li>
<li>Statistically, signing in isn't always successful the first time–so a message
around making it easier next time has tangible value.</li>
</ul>
<h3 id="positioning-passkeys-as-an-alternative-to-passwords-and-not-yet-a-replacement">Positioning passkeys as an alternative to passwords and not yet a replacement <a class="headline-link" href="https://web.dev/passkey-google-ux/#positioning-passkeys-as-an-alternative-to-passwords-and-not-yet-a-replacement">#</a></h3>
<p>Initial user research shows that many users still want passwords as a backup
sign-in method. And not all users will have the <a href="https://support.google.com/accounts/answer/13548313?hl=en&amp;sjid=17510595681178318776-NA" rel="noopener">technology necessary to adopt
passkeys</a>.</p>
<p>So while the industry, Google included, is moving towards a &quot;passwordless
future&quot;, Google is intentionally positioning passkeys as a simple and secure
<strong>alternative</strong> to passwords. Google's UI focuses on the benefits of passkeys
and avoids language that implies getting rid of passwords.</p>
<h2 id="the-creation-moment">The creation moment <a class="headline-link" href="https://web.dev/passkey-google-ux/#the-creation-moment">#</a></h2>
<p>When users choose to enroll, they'll see a browser-specific UI modal that
enables them to create a passkey.</p>
<p>The passkey itself is shown with the industry-aligned icon and the information
used to create it. This includes the display name (a friendly name for your
passkey, like your user's real name) and the username (a unique name on your
service–an email address can work great here). When it comes to working with the
passkeys icon, <a href="https://media.fidoalliance.org/wp-content/uploads/2023/05/FIDO-Alliance-UX-Guidelines-for-Passkey-Creation-and-Sign-ins.pdf" rel="noopener">the FIDO alliance recommends using the proven passkeys
icon</a>–and
encourages making it your own with customizations.</p>
<p>Passkeys icon is shown consistently across the user journey to create a
familiarity with what the user will see when using or managing the passkey. The
passkey icon is never presented without context or supporting material.</p>
<figure>
<img alt="When users create their passkey, they&#x27;ll see this page" decoding="async" height="600" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1600 1600w" width="800" />
<figcaption>When users create their passkey, they'll see this page.</figcaption>
</figure>
<p>Above, we outlined how the user and the platform work together to create a
passkey. When the user clicks &quot;Continue&quot; they'll be presented with a unique UI
depending on the platform.</p>
<p>With that in mind, we learned through internal research that a confirmation
screen once the passkey is created can be very helpful in terms of comprehension
and closure at this step of the process.</p>
<figure>
<img alt="Once the passkey has been created, users will see this page" decoding="async" height="600" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/sNqODRG8qqaGQc8ygbjO.png?auto=format&w=1600 1600w" width="800" />
<figcaption>Once the passkey has been created, users will see this page.</figcaption>
</figure>
<p>The confirmation screen is a deliberate ‘pause' to bookend the journey of
introducing a user to passkeys and going through the process of creating one of
their own. As it is (likely) the first time a user has engaged with passkeys,
this page aims to provide clear closure to the journey. We chose a standalone
page after trying some other tools like smaller notifications, and even a
post-creation email–simply to provide a structured, stable end to end
experience.</p>
<p>Once the user clicks &quot;Continue&quot; here, they're brought to their destination.</p>
<figure>
<img alt="When users sign in again, they&#x27;ll likely see this page" decoding="async" height="600" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/u7ugXsWYbGcylhCWZ21M.png?auto=format&w=1600 1600w" width="800" />
<figcaption>When users sign in again, they'll likely see this page.</figcaption>
</figure>
<h2 id="signing-in">Signing in <a class="headline-link" href="https://web.dev/passkey-google-ux/#signing-in">#</a></h2>
<p>Next time a user tries to sign in, they'll be greeted with this page. This uses
the same layout, illustration, and primary call to action to evoke the first
‘creation' experience outlined above. Once the user has made a choice to enroll
in passkeys, this page should feel familiar and they will recognize what steps
they need to take to sign in.</p>
<figure>
<img alt="The user will use this WebAuthn UI to sign in" decoding="async" height="600" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/kPbCZqaBDx5AFTZyi54a.png?auto=format&w=1600 1600w" width="800" />
<figcaption>The user will use this WebAuthn UI to sign in.</figcaption>
</figure>
<p>The same principle of familiarity applies here. Intentionally, this uses the
same iconography, illustration, layout and text. The text within the WebAuthn UI
is kept brief, broad, and re-usable–so everyone can use this both for
authentication and reauthentication.</p>
<h2 id="passkeys-management">Passkeys management <a class="headline-link" href="https://web.dev/passkey-google-ux/#passkeys-management">#</a></h2>
<p>Introducing a whole new page within the Google Account settings pages required
careful consideration to ensure a cohesive, intuitive, and consistent user
experience.</p>
<p>To achieve this, we analyzed the patterns regarding navigation, content,
hierarchy, structure, and established expectations that existed across the
Google Account.</p>
<figure>
<img alt="Passkeys management page in the Google Account" decoding="async" height="655" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format" srcset="https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/YLflGBAPWecgtKJLqCJHSzHqe2J2/C0xuS6j8vd98Y17jckE3.png?auto=format&w=1600 1600w" width="800" />
<figcaption>Passkeys management page in the Google Account.</figcaption>
</figure>
<h3 id="describe-passkeys-by-ecosystem">Describe passkeys by ecosystem <a class="headline-link" href="https://web.dev/passkey-google-ux/#describe-passkeys-by-ecosystem">#</a></h3>
<p>To create a high level category system that would be logical to understand we
settled on describing passkeys by
<a href="https://developers.google.com/identity/passkeys/supported-environments" rel="noopener">ecosystem</a>.
This way, a user could recognize where a passkey was created and where it is
used. Each identity provider (Google, Apple, and Microsoft) has a name for their
ecosystem, so we chose to use those (Google Password Manager, iCloud keychain,
and Windows Hello respectively).</p>
<p>To support this, we added additional metadata, such as when it was created, when
it was last used, and the specific OS that it was used on. In terms of user
management actions, the API only supports renaming, revoking, and creating.</p>
<p>Renaming allows users to assign personally meaningful names to passkeys, which
could help particular cohorts of users keep track and understand them more
easily.</p>
<p>Revoking a passkey doesn't delete it from the user's personal credential manager
(like Google Password Manager), but renders it unusable until it is set up
again. That's why we chose a cross, instead of a trash or delete icon, to
represent the action of revoking a passkey.</p>
<p>When describing the action of adding a passkey to their account, the phrase
&quot;Create passkey&quot; resonated better with users compared to &quot;Add a passkey.&quot; This
is a subtle language choice to distinguish passkeys from tangible, hardware
security keys (though it should be noted that <a href="https://support.google.com/accounts/answer/13548313?hl=en&amp;sjid=17510595681178318776-NA" rel="noopener">passkeys can be stored on some
hardware security
keys</a>).</p>
<h3 id="providing-additional-content">Providing additional content <a class="headline-link" href="https://web.dev/passkey-google-ux/#providing-additional-content">#</a></h3>
<p>Internal research showed that using passkeys is a relatively seamless and
familiar experience. However as with any new technology, there are lingering
questions and concerns that will come up for some users.</p>
<p>How the technology works behind the screen lock, what makes it more secure, and
the most common &quot;what if&quot; scenarios Google came across in testing are addressed
in <a href="https://support.google.com/accounts/answer/13548313?hl=en&amp;sjid=17510595681178318776-NA" rel="noopener">Google's passkey Help Center
content</a>.
Having support content ready with launch of passkeys is critical for an easy
transition for users on any site.</p>
<h3 id="falling-back-from-passkeys">Falling back from passkeys <a class="headline-link" href="https://web.dev/passkey-google-ux/#falling-back-from-passkeys">#</a></h3>
<p>Reverting to the old system is as simple as clicking &quot;try another way&quot; when a
user is asked to authenticate with a passkey. Additionally, exiting the WebAuthn
UI will start users on a path to try their passkey again, or sign into their
Google Account in traditional ways.</p>
<h2 id="conclusion">Conclusion <a class="headline-link" href="https://web.dev/passkey-google-ux/#conclusion">#</a></h2>
<p>We are still in the early days of passkeys, so when designing the user
experience keep a few principles in mind:</p>
<ul>
<li>Introduce passkeys when it's relevant to the user.</li>
<li>Highlight the benefits of passkeys.</li>
<li>Use opportunities to build familiarity the concept of passkeys.</li>
<li>Position passkeys as an alternative to passwords and not a replacement.</li>
</ul>
<p>The choices we made for passkeys for Google Accounts were informed by best
practices and internal research and we'll continue to evolve the user experience
as we gain new insights from users in the real world.</p>
</content>
<author>
<name>
Mitchell Galavan
</name>
</author>
<author>
<name>
Court Jacinic
</name>
</author>
<author>
<name>
Silvia Convento
</name>
</author>
</entry>
<entry>
<title>
Pyramid or Crab? Find a testing strategy that fits
</title>
<link href="https://web.dev/ta-strategies/"/>
<updated>
2023-07-26T00:00:00Z
</updated>
<id>
https://web.dev/ta-strategies/
</id>
<content type="text/html" mode="escaped">
<p>Welcome back! In the <a href="https://web.dev/ta-types">last article</a>, we laid down lots of groundwork about how to approach the different testing types and what they contain, and we clarified the testing type definitions. Remember our little meme image from before? We wondered how all those testing types we learned about could work together.</p>
<img alt="A cupboard with two drawers you can open at the same time." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/n3LPuwApNcCRT5S3zaoq.jpeg?auto=format&w=1600 1600w" width="800" />
<p>So next up, we will learn exactly that. This article will give an introduction on how to combine these testing types into a reasonable strategy that matches your project.</p>
<p>I want to share some recommendations on which testing strategies might fit your project, depending on its size. Let’s begin with a short overview—an attempt to generalize based on my own experience, so it can naturally deviate from your use case. I hope this is a good starting point:</p>
<div class="table-wrapper scrollbar">
<table>
<thead>
<tr>
<th>
Application size
</th>
<th>
Team composition
</th>
<th>
Reliance on manual testing
</th>
<th>
Testing strategy
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Small</td>
<td>Developers only</td>
<td>High</td>
<td>Testing Ice Cone<br />Testing Crab</td>
</tr>
<tr>
<td>Small</td>
<td>High</td>
<td>Developers & QA engineers</td>
<td>Testing Ice Cone<br />Testing Crab</td>
</tr>
<tr>
<td>Small</td>
<td>Developers only</td>
<td>Low</td>
<td>Test Pyramid</td>
</tr>
<tr>
<td>Large</td>
<td>Developers only</td>
<td>High</td>
<td>Testing Trophy<br />Testing Diamond</td>
</tr>
<tr>
<td>Large</td>
<td>Developers & QA engineers</td>
<td>High</td>
<td>Testing Trophy<br />Testing Crab</td>
</tr>
<tr>
<td>Large</td>
<td>Developers only</td>
<td>Low</td>
<td>Testing Trophy<br />Testing Honeycomb</td>
</tr>
</tbody>
</table>
</div>
<p>How did I come to the conclusions pictured in this table? What are the testing strategies mentioned? Let’s take a closer look to discover the answers.</p>
<h2 id="determine-testing-goals-what-do-we-want-to-achieve-with-these-tests">Determine testing goals: What do we want to achieve with these tests? <a class="headline-link" href="https://web.dev/ta-strategies/#determine-testing-goals-what-do-we-want-to-achieve-with-these-tests">#</a></h2>
<p>Before we can start building a good strategy, we need to find out where we want to go. What is our goal with testing? When do we consider that our application has been sufficiently tested?</p>
<p>Achieving high test coverage is often viewed as the ultimate goal for developers when it comes to testing. But is it always the best approach? In my opinion, there's a more critical factor to consider when deciding a testing strategy—serving our users’ needs.</p>
<p>As well as our role as developers, we all also use many other applications and devices. In this respect, we are the users and rely on all these systems to “just work”—that means we rely on countless developers to do their best to make their applications work. To turn this back around, as developers, we want to live up to this trust. So our first goal—whatever the project size—should always be to ship working software and thus serve our users. This means we must focus on our users' needs, especially in our tests. <a href="https://kentcdodds.com/about" rel="noopener">Kent C. Dodds</a> sums it up very well in <a href="https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests" rel="noopener">his post</a>:</p>
<blockquote>
<p>
The more your tests resemble the way your software is used, the more confidence they can give you.
</p>
<cite>
by Kent C. Dodds
</cite>
</blockquote>
<p>And I think this nails it. He describes it as becoming more confident in our tests. The closer we get to the users via choosing the corresponding testing type, the more confident we can trust our tests to have valid results. Or in other words, the higher up we climb the pyramid, the more confident we get. But wait, what is the pyramid? Don’t worry: we’ll cover this next.</p>
<h2 id="determining-test-strategies-how-to-choose-a-testing-strategy">Determining test strategies: How to choose a testing strategy <a class="headline-link" href="https://web.dev/ta-strategies/#determining-test-strategies-how-to-choose-a-testing-strategy">#</a></h2>
<p>Remember, as a first step, we want to determine which parts of our requirements need to be insured to be fulfilled, and how we want to achieve that. The goal behind that is to find out which types of testing to use, and then, with which granularity of testing we can reach the most confidence while also keeping an efficient cost structure. Many people approach this topic by using metaphors. Let’s take a deeper look at the most common ones, starting with the well-known classic.</p>
<img alt="A lot of shapes like pyramid, diamonds, ice cone, honeycombs and a trophy; representing test strategies." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/btUEUtD2bmqNwX2DcH4j.jpeg?auto=format&w=1600 1600w" width="800" />
<h3 id="the-classic-the-test-pyramid">The classic: The test pyramid <a class="headline-link" href="https://web.dev/ta-strategies/#the-classic-the-test-pyramid">#</a></h3>
<p>You will probably encounter the test automation pyramid as your initial metaphor as soon as you look up testing strategies. Mike Cohn introduced this concept in his book <em>Succeeding with Agile</em>. Later, the concept was expanded upon as the &quot;<a href="https://martinfowler.com/articles/practical-test-pyramid.html" rel="noopener">Practical Test Pyramid</a>&quot; by Martin Fowler. The visual representation of this pyramid is as follows:</p>
<img alt="The test pyramid." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/iEtr9phjNjENxQlFfJYv.jpeg?auto=format&w=1600 1600w" width="800" />
<p>As shown in this drawing, the test pyramid consists of three layers:</p>
<ol>
<li>
<p><strong>Unit</strong>. You find these tests on the base layer of the pyramid because they are fast execution and simple to maintain. This is due to their isolation and targeting of the most minor units. See this as an example of a typical <a href="https://github.com/leichteckig/phpmagazin-jest-example/blob/main/product.test.js" rel="noopener">unit test</a> testing a very small product.</p>
</li>
<li>
<p><strong>Integration</strong>. This is in the middle of the pyramid, as it is still acceptable when it comes to speed in execution but brings you the confidence of being closer to the user than unit tests can be. An example of an integration type test is an <a href="https://github.com/cypress-io/cypress-realworld-app/blob/develop/cypress/tests/api/api-users.spec.ts" rel="noopener">API test</a>; <a href="https://github.com/leichteckig/nuxt-leichteckig/blob/main/test/components/MediaGrid.spec.js" rel="noopener">component tests</a> can also be considered this type.</p>
</li>
<li>
<p><strong>E2E tests</strong> (also called <strong>UI tests</strong>). As we have seen, these tests simulate a genuine user and their interaction. These tests need more time to be executed and thus are more expensive—being placed at the top of the pyramid.</p>
</li>
</ol>
<h3 id="confidence-versus-resources">Confidence versus resources <a class="headline-link" href="https://web.dev/ta-strategies/#confidence-versus-resources">#</a></h3>
<p>As briefly covered already, the order of the layers is no coincidence. They show the priorities and the corresponding costs of the layers—thus giving you a clear picture of how many tests you should write from each layer. We have already seen this in the definition of the testing types.</p>
<p>As E2E tests, for example, are closest to our users, they give us the highest confidence that our application is working as intended. However, due to the complete application stack being present, and the computer simulation of a real user, they are potentially also the most expensive. So the confidence is in direct competition with the resources we need to execute the tests.</p>
<img alt="The test pyramid with arrows showing the direction of confidence and resources required for different testing types." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/DT57buwCB4uDyJp61Rzb.jpeg?auto=format&w=1600 1600w" width="800" />
<p>The pyramid tries to solve this competition by advising you to focus more on unit tests and strictly prioritize the cases covered by E2E tests: for example, your most crucial user journeys or the most vulnerable to defects. As Martin Fowler emphasizes, the two most essential points in Cohn’s pyramid are as follows:</p>
<ol>
<li>Write tests with different granularity.</li>
<li>The more high level you get, the fewer tests you should have.</li>
</ol>
<h2 id="pyramid-evolved-adaptations-of-the-test-pyramids">Pyramid evolved! Adaptations of the test pyramids <a class="headline-link" href="https://web.dev/ta-strategies/#pyramid-evolved-adaptations-of-the-test-pyramids">#</a></h2>
<p>For some years, discussions have revolved around the pyramid. The pyramid seems to oversimplify testing strategies, leaves out a lot of testing types, and no longer fits all real-world projects. Consequently, it may mislead us. So, has the pyramid fallen out of shape?
To answer this question, let’s take a look at the following <a href="https://twitter.com/rauchg/status/807626710350839808" rel="noopener">quote</a> from <a href="https://rauchg.com/about" rel="noopener">Guillermo Rauch</a>:</p>
<blockquote>
<p>
Write tests. Not too many. Mostly integration.
</p>
<cite>
by Guillermo Rauch
</cite>
</blockquote>
<p>It’s one of the most commonly cited quotes on this subject, so let’s break it down:</p>
<ul>
<li>Write tests: Not only because it builds trust, but also because it saves time in maintenance.</li>
<li>Not too many: 100% coverage is not always good, because then your testing is unprioritized and there will be a lot of maintenance.</li>
<li>Mostly integration: Here again the emphasis is on integration tests: they have the most business value by giving you a daily high confidence level while maintaining a reasonable execution time.</li>
</ul>
<p>This leads us to overthink the testing pyramid and shift our focus to integration testing. Over the last few years, many adaptations have been raised, so let’s look at the most common ones.</p>
<h3 id="test-diamond">Test diamond <a class="headline-link" href="https://web.dev/ta-strategies/#test-diamond">#</a></h3>
<p>The first adaptation I want to showcase tackles the over-emphasis on unit testing, as seen in the test pyramid. Imagine this situation: you have reached 100% coverage on unit tests. However, in the next refactoring, many of these unit tests will need to be updated, and you might be tempted to skip them. So they erode.</p>
<p>As a result, and together with the higher priority on integration testing, the following shape may arise:</p>
<img alt="The test diamond." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/vSFAkoSqbL4p984xf48k.jpeg?auto=format&w=1600 1600w" width="800" />
<p>The shape of the test pyramid has evolved more into a diamond. You can see the three layers from before, but with a different size and—in the case of the unit layer—with a slightly different shape:</p>
<ul>
<li>Unit: Write unit tests the way we defined them before. However, we’ll consider that they erode, so we’ll prioritize and cover the most critical cases here.</li>
<li>Integration: The integration tests we know, testing the combination of single units.</li>
<li>E2E: This layer handles the UI tests similar to the test pyramid. Take care to only write E2E tests for the most critical test cases.</li>
</ul>
<h3 id="testing-honeycomb">Testing honeycomb <a class="headline-link" href="https://web.dev/ta-strategies/#testing-honeycomb">#</a></h3>
<p>There is another adaptation similar to the test diamond but further specialized for microservices-based software systems. The testing honeycomb is another visual metaphor for the granularity/scope of and amounts of tests to write for a microservices-based software system. It's an adaptation of the traditional test pyramid specifically for <a href="https://notes.paulswail.com/public/Testing+microservices" rel="noopener">testing microservices</a>, introduced by <a href="https://engineering.atspotify.com/2018/01/testing-of-microservices/" rel="noopener">Spotify</a>. Due to their small size, the most considerable complexity in a microservice is not within the service itself, but in how it interacts with others. So a testing strategy for a microservice should primarily focus on integration tests.</p>
<img alt="The testing honeycomb." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/mrM4QK1kEZgvRvltyiMn.jpeg?auto=format&w=1600 1600w" width="800" />
<p>This way, a shape is formed that reminds us of a honeycomb, thus the name. In it, the following layers are used:</p>
<ul>
<li>Integrated tests: The article by Spotify uses a quote from <a href="https://blog.thecodewhisperer.com/permalink/integrated-tests-are-a-scam" rel="noopener">J. B. Rainsberger</a> to define this layer: “A test that will pass or fail based on the correctness of another system.” This means these tests have external dependencies that we need to consider, and vice versa—we could break the tests of other systems. Similar to E2E tests in other metaphors, we should use them carefully for the most essential cases only.</li>
<li>Integration tests: Similar to other adaptations, we should focus on this layer—containing tests to verify the correctness of our service in a more isolated fashion, but still in combination with other services. That means the tests will include some other systems too: focusing on the interaction points, for example, via API tests.</li>
<li>Tests on implementation details: These tests can resemble unit tests—this means on parts of the code that are naturally isolated and thus have their own internal complexity.</li>
</ul>
<p>If you want to find out more about this testing strategy, I advise you to read the post <a href="https://martinfowler.com/articles/2021-test-shapes.html" rel="noopener">comparing the test pyramid to the honeycomb</a> by Martin Fowler, alongside the <a href="https://engineering.atspotify.com/2018/01/testing-of-microservices/" rel="noopener">original article from Spotify</a>.</p>
<h3 id="testing-trophy">Testing trophy <a class="headline-link" href="https://web.dev/ta-strategies/#testing-trophy">#</a></h3>
<p>Alright, we already see a particular focus on integration tests. However, another type we mentioned in the previous article is not testing in theory but is still an important aspect we should consider in a testing strategy. I’m talking about static analysis, which is missing in the test pyramid and in most of the adaptations we have seen until now. There’s one adaptation, though, which takes static analysis into account while maintaining the focus on integration tests. It’s called the testing trophy, originating from the earlier quote by Guillermo Rauch and developed by Kent C. Dodds:</p>
<img alt="The testing trophy." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/ULNWIc7KY4jVjxPW5CdX.jpeg?auto=format&w=1600 1600w" width="800" />
<p>The testing trophy is a metaphor depicting the granularity of tests in a slightly different way, distributing your tests into the following four testing types:</p>
<ul>
<li><strong>Static analysis</strong> plays a vital role in this metaphor. This way, you will catch typos, type errors, and other bugs by merely running the debugging steps already outlined.</li>
<li><strong>Unit tests</strong> should ensure that your smallest unit is appropriately tested, but the testing trophy won’t emphasize them to the same extent as the test pyramid.</li>
<li><strong>Integration</strong> is the main focus as it balances out the cost and the higher confidence in the best way, as with other adaptations.</li>
<li><strong>UI tests</strong>, including E2E and visual tests, are at the top of the testing trophy, similar to their role in the test pyramid.</li>
</ul>
<p>To read more about the testing trophy, I can highly recommend the <a href="https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests" rel="noopener">blog post by Kent C. Dodds</a> on this subject.</p>
<h2 id="some-more-ui-focused-approaches">Some more UI-focused approaches <a class="headline-link" href="https://web.dev/ta-strategies/#some-more-ui-focused-approaches">#</a></h2>
<p>That’s all well and good. However, no matter if we call our strategy a “pyramid”, “honeycomb,” or “diamond”, there’s still something missing. While test automation is valuable, it's important to remember that manual testing is still essential. Automated testing should alleviate routine tasks, freeing testers to concentrate on crucial areas. Rather than replace manual testing, automation should complement it. Is there a way to integrate manual testing with automation for optimal results?</p>
<h3 id="testing-ice-cone-and-testing-crab">Testing ice cone and testing crab <a class="headline-link" href="https://web.dev/ta-strategies/#testing-ice-cone-and-testing-crab">#</a></h3>
<p>There are indeed two adaptations of the testing pyramid that focus more on these UI-focused ways of testing. Both share the advantage of high confidence, but naturally—due to the slower test execution—they are more costly.</p>
<p>The first one—the test ice cone, also known as the testing pizza if you leave out the manual testing step—looks like the pyramid in reverse.</p>
<img alt="The testing ice cone." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/QdBKM36jvq93jrERrSCP.jpeg?auto=format&w=1600 1600w" width="800" />
<p>As a result, the following layers will be showcased with the following granularity: the greater focus is on manual or UI testing, with the least focus on unit testing. It often happens with projects where the developers started work with only a few thoughts on testing. However, this testing strategy is considered an anti-pattern and rightfully so—because of its high costs in resources and manual work.</p>
<p>Similar to the test ice cone, but with a more drawn-out focus on E2E and visual testing, is the testing crab:</p>
<img alt="The testing crab." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/uY4XiFIldA1JySM9ZbHD.jpeg?auto=format&w=1600 1600w" width="800" />
<p>This testing strategy includes one more aspect: it should verify that our application functions and looks good. So this is the first testing strategy that highlights the importance of <a href="https://docs.cypress.io/guides/tooling/visual-testing" rel="noopener">visual testing</a>, which we also briefly defined in the last article. Integration testing, divided into component and API testing, moves further into the background, and unit testing plays an even more minor role here. You can find further details on this testing strategy in this <a href="https://changelog.com/posts/the-testing-pyramid-should-look-more-like-a-crab" rel="noopener">article on the testing crab</a>.</p>
<p>While being more costly, these two testing strategies have their place: for example, in smaller projects where fewer tests are needed, or less complexity needs to be covered. In this case, a full-blown testing strategy focusing on integration testing might be over-engineered.</p>
<h2 id="practical-advice-lets-strategize">Practical advice: Let’s strategize! <a class="headline-link" href="https://web.dev/ta-strategies/#practical-advice-lets-strategize">#</a></h2>
<p>So we have now learned about the most common testing strategies. We started with the classic—the test pyramid—and got to know its many adaptations. Now we need to evaluate them for our product and decide which might be the best for our use case. As I briefly mentioned at the beginning of this article, the answer to this question should start with everyone’s favorite response (although it’s no less accurate)—<strong>It depends</strong>.</p>
<img alt="It depends." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/u1yCzUoUXkXAHUCgyrz2.jpeg?auto=format&w=1600 1600w" width="800" />
<p>Choosing the most suitable testing strategy from the ones described—and even the ones we have left out—depends on your application. It needs to suit your architecture, your requirements, and last but not least, your users and their requirements. And this might differ from application to application. That’s totally fine: remember—our most important goal is to serve our users, not a textbook definition.</p>
<p>In reality, you can see this very clearly, as teams sometimes need to stop sticking to the textbook definitions of these strategies. Tests themselves are sometimes really difficult to separate out and define individually. Even Martin Fowler himself emphasizes the <a href="https://martinfowler.com/articles/2021-test-shapes.html" rel="noopener">positive aspect of differing definitions</a>, such as in the case of unit tests. As <a href="https://justin.searls.co/about/" rel="noopener">Justin Searls</a> states correctly in <a href="https://twitter.com/searls/status/1393385209089990659" rel="noopener">his tweet</a>:</p>
<blockquote>
<p>
[…] write expressive tests that establish clear boundaries, run quickly & reliably, and only fail for useful reasons.
</p>
<cite>
by Justin Searls
</cite>
</blockquote>
<p>Focus on the tests that report actual errors which a user might encounter, and don’t get distracted from your goal. Tests should be designed to benefit the user, not just provide 100% coverage or to debate which percentage of which testing type to write.</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> This blog post was written by Ramona, with input and review from <a href="https://web.dev/authors/jecelynyeen/">Jecelyn Yeen</a> (<a href="https://twitter.com/jecfish">Twitter</a>), and <a href="https://www.linkedin.com/in/michael-hablich-2128646/">Michael Hablich</a> (<a href="https://twitter.com/MHablich">Twitter</a>). Special thanks to <a href="https://www.linkedin.com/in/sofia-yemelianova/">Sofia Emelianova</a> for supporting the publication process. </div></aside>
</content>
<author>
<name>
Ramona Schwering
</name>
</author>
</entry>
<entry>
<title>
How Back/forward Cache Helped Yahoo! JAPAN News Increase Revenue by 9% on Mobile
</title>
<link href="https://web.dev/yahoo-japan-news-bfcache/"/>
<updated>
2023-07-25T00:00:00Z
</updated>
<id>
https://web.dev/yahoo-japan-news-bfcache/
</id>
<content type="text/html" mode="escaped">
<blockquote>
<p><a href="https://web.dev/bfcache/">Back/forward cache</a> (or bfcache) is a browser optimization that enables instant back and forward navigation. It significantly improves the browsing experience for users, especially for websites that involve many back and forth navigations.</p>
<p><cite>web.dev article on bfcache </cite></p>
</blockquote>
<p>Yahoo! JAPAN News, one of the most popular news platforms in Japan, drove a concerted effort to improve their bfcache hit rate and saw significant user experience and business improvements as a result. Specifically, the results of the A/B test they conducted showed that pages that use bfcache had a <strong>9% increase in ads revenue</strong>.</p>
<p>This case study will explain how Yahoo! JAPAN News removed the blockers for bfcache, and how bfcache drastically improved the user experience.</p>
<h2 id="removing-blockers-for-bfcache">Removing blockers for bfcache <a class="headline-link" href="https://web.dev/yahoo-japan-news-bfcache/#removing-blockers-for-bfcache">#</a></h2>
<p>bfcache has been available since Chrome 86, and is also available on all modern browsers. However, taking full advantage of bfcache requires removing potential blockers on one's website. Some major blockers that Yahoo! JAPAN News faced were:</p>
<ol>
<li>Use of <code>unload</code> handlers</li>
<li>Use of the <a href="https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control#no-store" rel="noopener"><code>no-store</code> directive</a> on <code>Cache-control</code> headers</li>
</ol>
<p>You can check what major blockers there are for your website by going to <strong>Chrome Dev Tools &gt; Applications &gt; Back/forward Cache</strong> (<a href="https://web.dev/bfcache/#test-to-ensure-your-pages-are-cacheable">more details</a>), or by using the <a href="https://developer.chrome.com/docs/web-platform/bfcache-notrestoredreasons/" rel="noopener"><code>notRestoredReasons</code> API</a> to get a more comprehensive view of blockers based on actual usage in the field.</p>
<p>Here's how Yahoo! JAPAN News has removed their blockers:</p>
<ul>
<li><strong>Unload Handlers:</strong> Use the <code>pagehide</code> event instead of <code>unload</code> event, as the <code>unload</code> event is <a href="https://web.dev/bfcache/#never-use-the-unload-event">very unreliable</a>. Also, <code>permission-policy: unload</code> was <a href="https://chromestatus.com/feature/5579556305502208" rel="noopener">launched in Chrome 115</a> so that the websites can reliably remove <code>unload</code> handlers for specific origins. Chrome is also planning to <a href="https://github.com/fergald/docs/blob/master/explainers/permissions-policy-deprecate-unload.md#logistics-of-deprecation" rel="noopener">gradually deprecate <code>unload</code> handlers</a>.</li>
<li><strong><code>Cache-control: no-store</code></strong> (or CCNS for short): Changing the <code>Cache-control</code> header from <strong><code>no-store</code></strong> to <strong><code>no-cache</code></strong> can enable bfcache. Chrome is also planning to start <a href="https://chromestatus.com/feature/6705326844805120" rel="noopener">caching for bfcache even with a <code>no-store</code> header in certain circumstances</a>.</li>
</ul>
<p>CCNS is intended for pages that should never be cached under any circumstances. This comes with the caveat that any page with CCNS will not be able to benefit from any caching technology, including CDN edge servers and local caches.</p>
<p>If you have a CCNS header, this is a great opportunity to discuss what the right <code>Cache-control</code> strategies are for your website. Here are the main differences between <code>no-store</code> and <code>no-cache</code>.</p>
<div class="table-wrapper scrollbar">
<table>
<thead>
<tr>
<th><code>Cache-control: <strong>no-store</strong></code></th>
<th><code>Cache-control: <strong>no-cache</strong></code></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<ul>
<li>The response is not allowed to be stored in caches.</li>
<li>Consequently, the response is fetched in full on every request.</li>
<li>This should be used for private responses.</li>
</ul>
</td>
<td>
<ul>
<li>The response is allowed to be stored in caches as long as it's revalidated with the server before each use.</li>
<li>This should be public responses you want revalidated every time (for example, the home page of a news website - though even then a very short caching time can improve performance and offload work from the main servers).</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
<p>If you are interested in learning more about <code>Cache-control</code> options, <a href="https://web.dev/http-cache/?hl=en#flowchart">this flowchart</a> is a great help.</p>
<h2 id="impact-of-bfcache-in-numbers">Impact of bfcache in numbers <a class="headline-link" href="https://web.dev/yahoo-japan-news-bfcache/#impact-of-bfcache-in-numbers">#</a></h2>
<p>To measure the impact of bfcache, Yahoo! JAPAN News conducted an A/B test for 2 weeks, where they served a version of their pages with their bfcache fixes to one group, and a version with pages ineligible for bfcache to another. They picked the URL paths with a significant amount of traffic so that the test could achieve meaningful results. There were no other visual or functional difference between the 2 versions.</p>
<p>Here's a video comparing the website with bfcache and without bfcache. You can see that the website with bfcache enabled loads significantly faster during a back or forward navigation.</p>
<style>
.bfcache-video video {
height: auto;
}
</style>
<figure class="bfcache-video">
<video autoplay="" controls="" height="800" loop="" muted="" width="800" style="--vid-width: 800; --vid-height: 800"> <source src="https://storage.googleapis.com/web-dev-uploads/video/jL3OLOhcWUQDnR4XjewLBx4e3PC3/2qqiTs9XuedWvtjfKuMu.mp4" type="video/mp4" /> </video>
</figure>
<p>What's really promising is that the group with bfcache enabled had a <strong>significant increase in page views and ads revenue</strong>, especially on mobile devices.</p>
<p>Here are details about the impact observed by Yahoo! JAPAN News with their bfcache A/B test. (Further information can be found in <a href="https://techblog.yahoo.co.jp/entry/2023072430429932/" rel="noopener">their case study article</a>).</p>
<div class="table-wrapper scrollbar">
<table>
<thead>
</thead><td>
<strong>Metrics</strong>
</td>
<td>
<strong>Uplift % (mobile)</strong>
</td>
<td>
<strong>Uplift % (desktop)</strong>
</td>
<tbody>
<tr>
<td>bfcache hit rate</td>
<td>
<strong>+54.03 points</strong> (0.04% → 54.07%)
</td>
<td>+47.28 points (0.02% → 47.30%)</td>
</tr>
<tr>
<td>Page views</td>
<td>
<strong>+2.26%</strong>
</td>
<td>+0.65%</td>
</tr>
<tr>
<td>Ads revenue</td>
<td>
<strong>+9.0%</strong>
</td>
<td>+0.6%</td>
</tr>
</tbody>
</table>
</div>
<p>When back/forward navigations between pages become instantaneous with bfcache, users tend to stay on pages longer, thus increasing ad views, leading to an increase of ad revenue.</p>
<h2 id="bfcache-enhances-seamless-user-experience-on-the-website">bfcache enhances seamless user experience on the website <a class="headline-link" href="https://web.dev/yahoo-japan-news-bfcache/#bfcache-enhances-seamless-user-experience-on-the-website">#</a></h2>
<p>When pages load instantly, <strong>navigations feel more seamless.</strong></p>
<p>In Yahoo! JAPAN News, one of the major user journey is as follows:</p>
<ol>
<li>Go to the article list</li>
<li>Click on one article to read</li>
<li>Go back to the article list</li>
<li>Click on another article to read</li>
</ol>
<p>Before bfcache, when users finished reading an article (step 2), they had to wait for the article list page to load again. This could be a friction factor for users who just want to go back to the article list to pick out another article to read.</p>
<p>Another source of friction during backward navigation was the scroll position. In practice, the browser tries to restore the scroll position when a backward navigation happens. However, because of dynamically-added ads or other layout changes, the scroll position often gets incorrectly restored, which could cause users to lose their bearings or even leave the page. This is never an issue when a backward navigation is powered by bfcache: the scroll position is immediately and correctly restored.</p>
<figure>
<img alt="Two filmstrips of a backward navigation from an article to the article listing page. The top is a filmstrip of the process being handled with bfcache which takes 0.3 seconds, whereas the bottom is of the same process being handled without bfcache, which takes 3.3 seconds." decoding="async" height="343" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format" srcset="https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=200 200w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=228 228w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=260 260w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=296 296w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=338 338w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=385 385w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=439 439w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=500 500w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=571 571w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=650 650w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=741 741w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=845 845w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=964 964w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/WlJn1GZnDrSLpEPPHWAn.png?auto=format&w=1600 1600w" width="800" />
</figure>
<p>Now with bfcache, the friction in the user journey is gone—users can instantly navigate back to the article list page and pick another article to read without having to wait for the article list page to load.</p>
<p>The same thing happens when users browse from one article directly to another and back:</p>
<figure>
<img alt="An animated image showing the backward navigation flow from an article to the article listing page with and without bfcache. With bfcache, the backward navigation is not only faster, but the scroll position is accurately maintained. Without bfcache, these guarantees cannot be made." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format" srcset="https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=200 200w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=228 228w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=260 260w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=296 296w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=338 338w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=385 385w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=439 439w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=500 500w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=571 571w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=650 650w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=741 741w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=845 845w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=964 964w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/jL3OLOhcWUQDnR4XjewLBx4e3PC3/pk7QmKzBA49ADdcJGE7q.gif?auto=format&w=1600 1600w" width="800" />
</figure>
<p>In a nutshell, the benefits of using bfcache for Yahoo! JAPAN News includes:</p>
<ul>
<li>Increased pageviews: Users were more likely to navigate within the website when pages were cached with bfcache.</li>
<li>Increased revenue: As a result of increased pageviews per session, ads impression increased, which resulted in a 9% increase in revenue on mobile compared with the test group without bfcache.</li>
</ul>
<h2 id="conclusion">Conclusion <a class="headline-link" href="https://web.dev/yahoo-japan-news-bfcache/#conclusion">#</a></h2>
<p>In short, bfcache not only makes your website instant, but can also reduce friction in overall user experience and increase engagement within your website.</p>
<p>The Chrome team is continually looking at bfcache blockers—especially the two reasons listed in this article as they are common reasons bfcache is not used. In the future, these may not prevent bfcache usage, but there's no need to wait until then. You can benefit from bfcache by looking at your bfcache blockers and avoiding these common, and other less common, patterns.</p>
</content>
<author>
<name>
Yuriko Hirota
</name>
</author>
</entry>
<entry>
<title>
Three common types of test automation
</title>
<link href="https://web.dev/ta-types/"/>
<updated>
2023-07-12T00:00:00Z
</updated>
<id>
https://web.dev/ta-types/
</id>
<content type="text/html" mode="escaped">
<p>We've all been there: what is a recurring coding meme that happens all too often in real life?
<img alt="A cupboard with two drawers you cannot open at the same time." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/yl1OSGuWVIOsgLO6odFZ.jpeg?auto=format&w=1600 1600w" width="800" /></p>
<p>This meme sums it up quite nicely: each drawer works perfectly well individually, but in combination with the other drawer, they block each other and fail to function. You want both drawers to work well with each other and be operable at the same time.</p>
<img alt="The same cupboard but with two drawers you can open at the same time." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/2PY6rfmGkB26vX3qIbsj.jpeg?auto=format&w=1600 1600w" width="800" />
<p>Apply this to web development: you wrote some tests, maybe even achieved 100% test coverage, but your application still needs to work once other parts fall into place. The units may work well on their own but not in relation to each other. Writing some tests is crucial but it's only one part of the ideal test setup for your project. As a very first step, you need to determine what parts of the application quality you need to ensure and how you can achieve that.</p>
<p>Simply put, you need a plan before you start writing the actual test code. To approach the topic of how to test practically, let's start with a clean slate and answer two basic questions:</p>
<ul>
<li>How do you want to test?</li>
<li>What do you want to test?</li>
</ul>
<p>This article focuses on the general things you need to know to answer the first question. To start from a common ground, let's first learn what testing modes exist and then focus on the common types of testing. In later articles, we will answer the second question, combine the answers, and find the testing strategy that works best for your project. Let's go! 🙌</p>
<h2 id="start-with-the-basics-general-testing-modes">Start with the basics: General testing modes <a class="headline-link" href="https://web.dev/ta-types/#start-with-the-basics-general-testing-modes">#</a></h2>
<p>When answering the question of how to test, the first point to clarify is very abstract. Should you test manually or let a computer take over? It's important, however, not to fall into binary thinking here.</p>
<h3 id="manual-testing-versus-automated-testing">Manual testing versus automated testing <a class="headline-link" href="https://web.dev/ta-types/#manual-testing-versus-automated-testing">#</a></h3>
<p>If you ask quality assurance engineers to define testing, they will probably break it down into two &quot;modes&quot; first:</p>
<ul>
<li><strong>Manual testing</strong>. This is a typical testing method conducted by actual people. A quality assurance engineer click through the application, check if it works and, at the same time, try to break it. The most common way is exploratory testing, where the engineer investigates the application using their knowledge of the application against a predefined path or checklist.</li>
<li><strong>Automated testing</strong>. This is a type of testing conducted by a computer. Quality assurance engineers implement it to automate away repetitive and monotonous tests.</li>
</ul>
<p>This series of guides will mostly focus on automated testing. However, you shouldn't focus on only one way of testing. Even if automation saves a lot of time and effort, humans and manual testing will always play a vital role. Rather, test automation should free up people to focus on exploratory testing and creative problem-solving. For example, ensuring the quality of user experiences or protecting the high-risk business logic. In other words, automation has your back. ❤️</p>
<h3 id="opaque-box-versus-clear-box">Opaque box versus clear box <a class="headline-link" href="https://web.dev/ta-types/#opaque-box-versus-clear-box">#</a></h3>
<p>So, you have defined the general modes of testing. However, that's not enough yet. To plan the testing strategy, there is one more question to answer: should you know how your application works under the hood or is it better to test without this knowledge? Depending on the answer, there are two procedures to choose from for deriving and selecting test cases:</p>
<ul>
<li><strong>Opaque box testing</strong> (or black box testing). It is based on analyzing a component or system's functional or non-functional requirements (specifications) without considering its internal structure.</li>
<li><strong>Clear box testing</strong> (or white box testing) is a procedure that takes into account the internal structure of said box. In other words, how your application works under the hood.</li>
</ul>
<p>Both procedures can be applied to manual and automated testing. However, some aspects of general testing modes may focus more on one of the two—we will cover that later. For now, let's further break down test automation into types.</p>
<h2 id="test-automation-types-how-do-you-want-to-test">Test automation types: How do you want to test? <a class="headline-link" href="https://web.dev/ta-types/#test-automation-types-how-do-you-want-to-test">#</a></h2>
<p>As you get closer to answering the &quot;how&quot; question, you have already decided to do some manual testing. However, choosing and applying test automation types is a bit more challenging. The types of automation testing are closely related to the metrics you want to create in your projects. So let's take a closer look at the most important ones.</p>
<p>As illustrated in the meme mentioned earlier, you have already come across two types: unit testing and integration testing. End-to-end testing is the third important one to consider. But that isn't all of them still. Let's take a closer look.</p>
<h3 id="unit-testing">Unit testing <a class="headline-link" href="https://web.dev/ta-types/#unit-testing">#</a></h3>
<p>Unit testing is a testing type in which minor testable parts or units of an application are individually and independently tested for proper operation. These units can vary in scope from functions, classes, or interfaces, to services or complete components. Their primary attributes are execution speed, isolation, and comfortable maintainability. If you want to dive deeper into unit testing, head over to this <a href="https://en.wikipedia.org/wiki/Unit_testing" rel="noopener">guide on unit testing</a>.</p>
<img alt="A simplified depiction of unit testing showing input and output." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/kVCbDIZN23OUGwOdpJmm.jpeg?auto=format&w=1600 1600w" width="800" />
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> Possible tools include but aren't limited to <a href="https://vitest.dev/">Vitest</a> and <a href="https://jestjs.io/">Jest</a>. </div></aside>
<h3 id="integration-testing">Integration testing <a class="headline-link" href="https://web.dev/ta-types/#integration-testing">#</a></h3>
<p>Integration testing focuses on interactions between components or systems. In other words, on how well they work together. Typical examples of integration tests are API or component tests.</p>
<img alt="A simplified depiction of integration testing showing how two unit working together." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/1dxHGzPGPDgkMqRMj46o.jpeg?auto=format&w=1600 1600w" width="800" />
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> The tools you may consider using are often the same as those mentioned in the <a href="https://web.dev/ta-types/#unit-testing">unit testing section</a> and can also include frameworks providing component testing, for example, <a href="https://webdriver.io/">WebdriverIO</a> and <a href="https://www.cypress.io/">Cypress</a>. </div></aside>
<h3 id="end-to-end-testing">End-to-end testing <a class="headline-link" href="https://web.dev/ta-types/#end-to-end-testing">#</a></h3>
<p>These tests are often called UI tests and this name explains their function even better. These tests interact with your application's UI, including the complete application stack, and test your application from one end to the other.</p>
<img alt="A simplified depiction of end-to-end testing showing a computer as a robot, looking at a workflow." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/9ZWWlop306SoGFP9rbeH.jpeg?auto=format&w=1600 1600w" width="800" />
<p>They resemble a system test if you refer to the theory of quality assurance. These tests simulate a genuine user and their interactions. End-to-end tests take more runtime because they involve the whole system and more runtime requires more computing power. As a result, this additional effort results in higher maintenance costs.</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> The tools you might use for end-to-end testing include but aren't limited to <a href="https://webdriver.io/">WebdriverIO</a>, <a href="https://www.cypress.io/">Cypress</a>, <a href="https://playwright.dev/">Playwright</a>, <a href="https://www.selenium.dev/">Selenium</a>. </div></aside>
<h4 id="visual-ui-testing">Visual UI testing <a class="headline-link" href="https://web.dev/ta-types/#visual-ui-testing">#</a></h4>
<p>An interesting subcategory of UI tests is visual tests. These tests are extended end-to-end tests that provide a means to verify the visible output of an application. Such a test takes a screenshot after a change and another screenshot containing the “status quo” (or golden file), then provides those results to a human reviewer to inspect and check. In other words, it helps find “visual bugs” in the appearance of a page, beyond purely functional bugs and not explicitly written down into assertions.</p>
<h3 id="static-analysis">Static analysis <a class="headline-link" href="https://web.dev/ta-types/#static-analysis">#</a></h3>
<p>There's one more thing to introduce here: static analysis. It isn't a testing type in the textbook sense. However, it will be an essential aspect in quality assurance strategies later on. You can imagine it working like a spell check function: it scans your code for more significant defects and syntax errors without running the program, thus detecting code style issues. This simple measure can prevent many bugs. This is a good point to learn about Static Analysis if you want to get to know it in more detail.</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> The tools you might use for static analysis include but aren't limited to <a href="https://eslint.org/">Eslint</a> and <a href="https://stylelint.io/">StyleLint</a>. </div></aside>
<h2 id="testing-in-all-shapes-how-does-this-all-work-together">Testing in all shapes: How does this all work together? <a class="headline-link" href="https://web.dev/ta-types/#testing-in-all-shapes-how-does-this-all-work-together">#</a></h2>
<p>While searching for answers to all these questions, you might find a possible solution in some analogies. In the web and testing communities specifically, developers tend to use these analogies to give you an idea of how many tests you should use of which type.</p>
<img alt="A lot of shapes like pyramid, diamonds, ice cone, honeycombs and a trophy; representing test strategies." decoding="async" height="450" loading="lazy" sizes="(min-width: 800px) 800px, calc(100vw - 48px)" src="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format" srcset="https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=200 200w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=228 228w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=260 260w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=296 296w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=338 338w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=385 385w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=439 439w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=500 500w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=571 571w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=650 650w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=741 741w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=845 845w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=964 964w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=1098 1098w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=1252 1252w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=1428 1428w, https://web-dev.imgix.net/image/dPDCek3EhZgLQPGtEG3y0fTn4v82/a96diycjrTQ2nVRpVgWH.jpeg?auto=format&w=1600 1600w" width="800" />
<p>The following five strategies depicted in this image are the most common ones:</p>
<ul>
<li>Test Pyramid</li>
<li>Test Diamond</li>
<li>Test Ice Cone (also known as Test Pizza)</li>
<li>Test Honeycomb</li>
<li>Test Trophy</li>
</ul>
<p>This is truly a lot of information to process. How should you decide on a matching test strategy based on all this? Don't worry, we've got you covered. In the next article, we will discuss these different strategies in more detail and explain how to choose the best fit for your project. Stay tuned! 🔥</p>
<aside class="aside flow bg-state-info-bg color-state-info-text"><div class=" flow"> This blog post was written by Ramona, with input and review from <a href="https://web.dev/authors/jecelynyeen/">Jecelyn Yeen</a> (<a href="https://twitter.com/jecfish">Twitter</a>), <a href="https://www.linkedin.com/in/michael-hablich-2128646/">Michael Hablich</a> (<a href="https://twitter.com/MHablich">Twitter</a>), and <a href="https://www.linkedin.com/in/sofia-yemelianova/">Sofia Emelianova</a>. </div></aside>
</content>
<author>
<name>
Ramona Schwering
</name>
</author>
</entry>
<entry>
<title>
New to the web platform in June
</title>
<link href="https://web.dev/web-platform-06-2023/"/>
<updated>
2023-06-30T00:00:00Z
</updated>
<id>
https://web.dev/web-platform-06-2023/
</id>
<content type="text/html" mode="escaped">
<h2 id="stable-browser-releases">Stable browser releases <a class="headline-link" href="https://web.dev/web-platform-06-2023/#stable-browser-releases">#</a></h2>
<p>In June 2023 <a href="https://developer.mozilla.org/docs/Mozilla/Firefox/Releases/114" rel="noopener">Firefox 114</a> became stable, so it's a single browser issue this month. Check out the beta browser releases section for details of several features that are about to become interoperable once those betas become stable.</p>
<aside class="aside flow bg-state-bad-bg color-state-bad-text"><p class="cluster color-state-bad-text"><span class="aside__icon box-block "><svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Error sign"> <path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 15v-2h2v2h-2zm0-10v6h2V7h-2z"></path> </svg></span><strong>Caution</strong></p><div class=" flow"> We include browser compatibility data pulled from MDN in these posts which may not have been updated yet for very recent browser releases. The post will show the correct information as soon as it appears in the <a href="https://github.com/mdn/browser-compat-data/releases">browser-compat-data release</a>. </div></aside>
<h3 id="webtransport-api">WebTransport API <a class="headline-link" href="https://web.dev/web-platform-06-2023/#webtransport-api">#</a></h3>
<p>Firefox 114 includes the <a href="https://developer.mozilla.org/docs/Web/API/WebTransport_API" rel="noopener">WebTransport API</a>, a modern update to WebSockets providing support for multiple streams, unidirectional streams, and out-of-order delivery.</p>
<div class="wdi-browser-compat">
<span class="wdi-browser-compat__label">Browser support</span>
<ul class="wdi-browser-compat__items">
<li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="chrome">
<span class="visually-hidden">Chrome 97, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
97
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="firefox">
<span class="visually-hidden">Firefox preview, Preview</span>
</span>
<span class="wdi-browser-compat__version" data-compat="preview" title="Preview" aria-label="Preview">
<p></p></span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="edge">
<span class="visually-hidden">Edge 97, Supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="yes" title="Supported" aria-label="Supported">
97
</span>
</li><li class="wdi-browser-compat__item">
<span class="wdi-browser-compat__icon" data-browser="safari">
<span class="visually-hidden">Safari, Not supported</span>
</span>
<span class="wdi-browser-compat__version" data-compat="no" title="Not supported" aria-label="Not supported"><p></p>
<p></p></span>
</li><p></p>
</ul>