1 00:00:06,570 --> 00:00:08,700 - The testing library is quite flexible 2 00:00:08,700 --> 00:00:10,500 and it contains lots of different ways 3 00:00:10,500 --> 00:00:12,390 in which you can search for content. 4 00:00:12,390 --> 00:00:14,790 In fact, there are three categories of functions 5 00:00:14,790 --> 00:00:18,870 that you can use to locate content using testing library. 6 00:00:18,870 --> 00:00:21,030 The first category, there's a bunch of functions 7 00:00:21,030 --> 00:00:22,740 called get by something. 8 00:00:22,740 --> 00:00:25,170 Get by text, for example. 9 00:00:25,170 --> 00:00:30,170 The get by functions, they look for a single match. 10 00:00:30,240 --> 00:00:35,040 If it finds no matches, or if it finds multiple matches, 11 00:00:35,040 --> 00:00:36,870 it'll give you back an error. 12 00:00:36,870 --> 00:00:40,803 So get by only works with a single result. 13 00:00:42,000 --> 00:00:44,970 Query by is a little bit more flexible. 14 00:00:44,970 --> 00:00:47,850 It'll return one matching node, if it finds it, 15 00:00:47,850 --> 00:00:50,190 or null if it doesn't find anything, 16 00:00:50,190 --> 00:00:51,810 But again, it returns an error, 17 00:00:51,810 --> 00:00:54,393 it throws an error if there are many matches. 18 00:00:55,380 --> 00:00:57,120 The third category is a bit different. 19 00:00:57,120 --> 00:01:01,020 There are find by functions, like find by text. 20 00:01:01,020 --> 00:01:04,950 This function or this group of functions returns a promise. 21 00:01:04,950 --> 00:01:08,040 That promise resolves successfully 22 00:01:08,040 --> 00:01:10,890 if it finds one match and it rejects 23 00:01:10,890 --> 00:01:14,880 if it finds either zero or many matches. 24 00:01:14,880 --> 00:01:16,740 So each of these functions are geared up 25 00:01:16,740 --> 00:01:19,230 to find one match, ideally. 26 00:01:19,230 --> 00:01:21,300 If you wanna find multiple matches, 27 00:01:21,300 --> 00:01:25,260 then there are similar functions called get by... 28 00:01:25,260 --> 00:01:29,580 Get all by, query all by and find all by. 29 00:01:29,580 --> 00:01:30,780 Okay? The same functions, 30 00:01:30,780 --> 00:01:33,030 but instead of just finding one node, 31 00:01:33,030 --> 00:01:35,163 they find all matching nodes. 32 00:01:36,150 --> 00:01:38,400 Okay, so we have these three categories of functions, 33 00:01:38,400 --> 00:01:42,120 get by, find by, and query by. 34 00:01:42,120 --> 00:01:44,520 In each of those functions, you've gotta specify 35 00:01:44,520 --> 00:01:47,100 the text that you're looking for. 36 00:01:47,100 --> 00:01:49,020 And it turns out there are three different ways 37 00:01:49,020 --> 00:01:50,310 to specify the text. 38 00:01:50,310 --> 00:01:52,230 So you have a lot of flexibility here. 39 00:01:52,230 --> 00:01:55,290 Three different groups of functions and for each function, 40 00:01:55,290 --> 00:01:59,460 three different ways to specify the text. 41 00:01:59,460 --> 00:02:02,130 So you can say I'm looking for an element 42 00:02:02,130 --> 00:02:05,550 whose text is exactly this string 43 00:02:05,550 --> 00:02:08,430 or you can specify a regular expression 44 00:02:08,430 --> 00:02:11,820 or you can specify a callback function 45 00:02:11,820 --> 00:02:14,400 where you've got some kind of complicated algorithm 46 00:02:14,400 --> 00:02:17,250 to figure out what elements you're looking for. 47 00:02:17,250 --> 00:02:19,320 So when you call any other functions, 48 00:02:19,320 --> 00:02:23,670 you can say find a node that matches this string 49 00:02:23,670 --> 00:02:27,767 or this regular expression or call this callback function. 50 00:02:27,767 --> 00:02:30,480 And if that callback function returns true, 51 00:02:30,480 --> 00:02:32,430 that's the element I'm looking for. 52 00:02:32,430 --> 00:02:34,860 I'm gonna show you an example of all of this 53 00:02:34,860 --> 00:02:36,630 in the next few minutes. 54 00:02:36,630 --> 00:02:38,730 So go into this demo folder. 55 00:02:38,730 --> 00:02:41,283 Testing library, types of query. 56 00:02:42,300 --> 00:02:43,133 Here it is. 57 00:02:44,190 --> 00:02:49,190 If you open that up in your code editor, it looks like this. 58 00:02:50,100 --> 00:02:52,350 So bit of housekeeping, first of all. 59 00:02:52,350 --> 00:02:54,060 We have the usual configuration. 60 00:02:54,060 --> 00:02:57,303 We've seen this at few times now, Babel config. 61 00:02:58,290 --> 00:03:02,873 It tells Babel to transpile my code to ECMAScript 15, 2015. 62 00:03:04,260 --> 00:03:06,390 We have jest config that makes sure 63 00:03:06,390 --> 00:03:08,760 that jest runs in jsdom mode, 64 00:03:08,760 --> 00:03:10,440 so it creates a document object 65 00:03:10,440 --> 00:03:12,600 for our webpage to access. 66 00:03:12,600 --> 00:03:17,600 And then package json enable the Babel transpilation 67 00:03:18,060 --> 00:03:20,760 and also to import the testing library, if you remember. 68 00:03:20,760 --> 00:03:25,020 So remember again that if you want to run these examples, 69 00:03:25,020 --> 00:03:27,210 you have to install these packages, 70 00:03:27,210 --> 00:03:31,320 open up a command prompt window, NPM install. 71 00:03:31,320 --> 00:03:33,990 It'll load these libraries into your local folder 72 00:03:33,990 --> 00:03:35,820 and then you're ready to go. 73 00:03:35,820 --> 00:03:37,470 So what we're gonna do over the next few minutes 74 00:03:37,470 --> 00:03:39,330 is I'm gonna show you examples 75 00:03:39,330 --> 00:03:42,150 of using the get by functions, 76 00:03:42,150 --> 00:03:45,900 the query by functions and the find by functions. 77 00:03:45,900 --> 00:03:50,490 Okay, just to give you a good example of each one of those. 78 00:03:50,490 --> 00:03:54,270 Okay, so we're gonna look at one test file 79 00:03:54,270 --> 00:03:56,670 that illustrates the get by family. 80 00:03:56,670 --> 00:04:00,240 And then the second test file illustrates the query by, 81 00:04:00,240 --> 00:04:03,210 where you may get back a result or no results. 82 00:04:03,210 --> 00:04:06,660 And then the find by functions where you have a callback. 83 00:04:06,660 --> 00:04:09,690 I'm just going to be using the single checks 84 00:04:09,690 --> 00:04:11,220 in each of these examples. 85 00:04:11,220 --> 00:04:13,050 It would be, you know, the same idea 86 00:04:13,050 --> 00:04:15,540 if you use the get all for example. 87 00:04:15,540 --> 00:04:19,383 Okay, so you can extrapolate the concept I'm sure. 88 00:04:20,370 --> 00:04:25,353 Right, so this is the first example using the get by tests. 89 00:04:26,640 --> 00:04:29,910 Okay, so using the get by tests, 90 00:04:29,910 --> 00:04:32,220 I've got some code that runs before each tests 91 00:04:32,220 --> 00:04:35,790 and then I've got three different tests to illustrate 92 00:04:35,790 --> 00:04:38,910 the three different ways of doing text matching. 93 00:04:38,910 --> 00:04:41,730 Right, oh, actually one other thing I need to say, 94 00:04:41,730 --> 00:04:43,590 a bit of housekeeping. 95 00:04:43,590 --> 00:04:48,240 Remember the screen object provided by testing library? 96 00:04:48,240 --> 00:04:50,433 Basically that's the document body. 97 00:04:51,270 --> 00:04:53,910 And then before each test, 98 00:04:53,910 --> 00:04:57,090 I load my document body with some simple HTML. 99 00:04:57,090 --> 00:04:59,280 And again, obviously I could have loaded this in 100 00:04:59,280 --> 00:05:01,170 from an actual HTML document. 101 00:05:01,170 --> 00:05:02,770 The principle would be the same. 102 00:05:03,960 --> 00:05:08,340 So we're gonna use the screen function, screen get by, 103 00:05:08,340 --> 00:05:11,070 and we're gonna give it three different types of check. 104 00:05:11,070 --> 00:05:14,130 To get by text, to get by regular expression, 105 00:05:14,130 --> 00:05:16,143 and to get via some kind of callback. 106 00:05:17,370 --> 00:05:19,770 Great. Okay, so first things first, then. 107 00:05:19,770 --> 00:05:23,610 At the top there, load some basic content into my document, 108 00:05:23,610 --> 00:05:25,203 which I can then test against. 109 00:05:26,220 --> 00:05:29,010 Okay, then in this first test, 110 00:05:29,010 --> 00:05:33,090 get an element via a string text match. 111 00:05:33,090 --> 00:05:35,703 So you call screen get by text. 112 00:05:36,570 --> 00:05:38,880 So basically document dot body. 113 00:05:38,880 --> 00:05:41,730 In my document body, get by text. 114 00:05:41,730 --> 00:05:46,020 This will only match, or this must match a single element. 115 00:05:46,020 --> 00:05:48,900 If there were multiple matches or no matches, 116 00:05:48,900 --> 00:05:50,670 this would throw an error. 117 00:05:50,670 --> 00:05:53,250 So in my document, hopefully, there was one element 118 00:05:53,250 --> 00:05:55,290 whose text is hello, 119 00:05:55,290 --> 00:05:57,270 and hopefully I'll get back a pointer to it. 120 00:05:57,270 --> 00:06:02,270 This is going to be a pointer to the element with hello. 121 00:06:02,280 --> 00:06:05,040 So when I get the text here, 122 00:06:05,040 --> 00:06:06,900 it should correct match correctly. 123 00:06:06,900 --> 00:06:09,150 Here, I'm using a regular expression, okay? 124 00:06:09,150 --> 00:06:12,360 Search for, again, screen, get by text, 125 00:06:12,360 --> 00:06:14,460 but I'm specifying a regular expression. 126 00:06:14,460 --> 00:06:18,210 Remember the i means case insensitive. 127 00:06:18,210 --> 00:06:21,990 I'm looking for a case insensitive text match. 128 00:06:21,990 --> 00:06:25,530 The letter h dot means any character. 129 00:06:25,530 --> 00:06:30,060 So h, any character, any character, any character, o. 130 00:06:30,060 --> 00:06:33,450 Find one element whose text matches that pattern. 131 00:06:33,450 --> 00:06:35,700 Okay, well that will match. 132 00:06:35,700 --> 00:06:37,770 And the inner HTML that we find, 133 00:06:37,770 --> 00:06:39,750 basically it finds that element 134 00:06:39,750 --> 00:06:43,860 and the inner HTML of that element should be hello. 135 00:06:43,860 --> 00:06:44,793 And it is. 136 00:06:46,080 --> 00:06:47,190 Okay. 137 00:06:47,190 --> 00:06:49,890 The third check is when you say, 138 00:06:49,890 --> 00:06:53,250 when you parse in a callback function, okay? 139 00:06:53,250 --> 00:06:55,053 So here's my callback function. 140 00:06:56,820 --> 00:07:01,820 This is the element that it would've checked against. 141 00:07:02,370 --> 00:07:03,490 Okay, so e 142 00:07:05,875 --> 00:07:09,610 is basically the element that it's trying to check against. 143 00:07:11,160 --> 00:07:14,280 C is the content of it, okay? 144 00:07:14,280 --> 00:07:16,833 So e will be this element. 145 00:07:17,670 --> 00:07:21,370 If the element's tag name in lowercase is div 146 00:07:22,260 --> 00:07:24,970 and the content length is five 147 00:07:26,190 --> 00:07:27,930 that's the element I'm looking for. 148 00:07:27,930 --> 00:07:31,170 Remember, whenever you call the get functions, 149 00:07:31,170 --> 00:07:35,220 they have to return a single match. 150 00:07:35,220 --> 00:07:38,610 So hopefully there will be a single element 151 00:07:38,610 --> 00:07:42,600 in my document whose content length is five 152 00:07:42,600 --> 00:07:46,080 and whose name of the element is div. 153 00:07:46,080 --> 00:07:49,200 It'll search for an element that has that characteristic. 154 00:07:49,200 --> 00:07:50,820 And if there's one element, 155 00:07:50,820 --> 00:07:52,800 it'll return me back a reference to it. 156 00:07:52,800 --> 00:07:55,110 And there is, it returns back a reference 157 00:07:55,110 --> 00:07:56,940 to this element here. 158 00:07:56,940 --> 00:08:01,260 So this kind of callback mechanism is quite useful 159 00:08:01,260 --> 00:08:03,990 when you've got a complicated check that you want to do. 160 00:08:03,990 --> 00:08:05,880 You're not just checking something simple, 161 00:08:05,880 --> 00:08:07,080 like the actual text, 162 00:08:07,080 --> 00:08:08,790 but it's something a bit more involved. 163 00:08:08,790 --> 00:08:10,050 You can have a callback function 164 00:08:10,050 --> 00:08:11,820 and effectively what will happen 165 00:08:11,820 --> 00:08:16,260 is the get by text function will call this arrow function 166 00:08:16,260 --> 00:08:19,260 on each element to check if it matches 167 00:08:19,260 --> 00:08:22,080 and hopefully we'll get a single match back 168 00:08:22,080 --> 00:08:24,183 whose inner HTML is correct. 169 00:08:25,664 --> 00:08:28,320 Okay, so if I run that test, 170 00:08:28,320 --> 00:08:31,050 you can run it yourself and it'll work. 171 00:08:31,050 --> 00:08:32,970 Okay, so that was the get by, 172 00:08:32,970 --> 00:08:35,970 where you wanna get back definitely one match. 173 00:08:35,970 --> 00:08:39,120 Next up, we're going to look at the query by functions. 174 00:08:39,120 --> 00:08:42,990 Similar idea, the same kind of text check in, 175 00:08:42,990 --> 00:08:45,630 but it allows you to maybe have a match 176 00:08:45,630 --> 00:08:48,090 or maybe not have a match. 177 00:08:48,090 --> 00:08:52,440 Okay, so query an element with a successful match. 178 00:08:52,440 --> 00:08:54,273 Here's my HTML that I've loaded. 179 00:08:55,230 --> 00:08:56,550 - Query by text. 180 00:08:56,550 --> 00:08:59,280 I'm saying hopefully I'll find either zero 181 00:08:59,280 --> 00:09:01,260 or one element that matches this. 182 00:09:01,260 --> 00:09:02,530 Find an element 183 00:09:03,750 --> 00:09:05,310 whose text matches 184 00:09:05,310 --> 00:09:08,370 h, something, something, something, o. 185 00:09:08,370 --> 00:09:10,320 Obviously, it's going to be that element. 186 00:09:10,320 --> 00:09:12,360 It'll gimme back the element. 187 00:09:12,360 --> 00:09:15,540 Okay, it's not null, because it should exist. 188 00:09:15,540 --> 00:09:17,790 And it says, yeah, there it is. 189 00:09:17,790 --> 00:09:18,960 Now, what about this one? 190 00:09:18,960 --> 00:09:22,320 Query by text is allowed to return null. 191 00:09:22,320 --> 00:09:24,360 If I give it some check, some test here 192 00:09:24,360 --> 00:09:27,690 that clearly isn't located in my document, 193 00:09:27,690 --> 00:09:30,990 getting back null is allowable for query by text. 194 00:09:30,990 --> 00:09:33,600 If you say get by, it would throw an error, 195 00:09:33,600 --> 00:09:36,480 but with query by, it's when you are trying to assure it. 196 00:09:36,480 --> 00:09:38,040 Does it exist or doesn't it? 197 00:09:38,040 --> 00:09:41,640 I'm checking that this should gimme back null, okay, 198 00:09:41,640 --> 00:09:44,613 because there is no such element in the document. 199 00:09:46,020 --> 00:09:48,570 That's the query by function. 200 00:09:48,570 --> 00:09:50,490 The third in the trilogy... 201 00:09:50,490 --> 00:09:52,410 Oh, let me just run that test first. 202 00:09:52,410 --> 00:09:54,120 It would, great. 203 00:09:54,120 --> 00:09:57,570 The third approach is when you call, find by. 204 00:09:57,570 --> 00:10:01,803 Remember, get by is one match, 205 00:10:02,640 --> 00:10:05,460 query by is one or zero matches, 206 00:10:05,460 --> 00:10:09,390 and find by, it basically returns a promise, 207 00:10:09,390 --> 00:10:12,960 and that promise will either resolve if it matches, 208 00:10:12,960 --> 00:10:16,320 or it'll reject if it doesn't. 209 00:10:16,320 --> 00:10:17,970 So let's have a look at this example. 210 00:10:17,970 --> 00:10:20,640 Again, I've loaded the same content initially. 211 00:10:20,640 --> 00:10:24,990 Screen find by, I give it the text that I'm trying to find, 212 00:10:24,990 --> 00:10:28,260 and the find by function returns a promise 213 00:10:28,260 --> 00:10:32,463 and if that promise succeeds, it'll call the then handler. 214 00:10:33,300 --> 00:10:35,280 Okay, so remember with promises, 215 00:10:35,280 --> 00:10:39,120 a promise basically resolves successfully, or it rejects. 216 00:10:39,120 --> 00:10:43,080 If it resolves successfully, then upon your promise object, 217 00:10:43,080 --> 00:10:44,940 this then returns a promise, 218 00:10:44,940 --> 00:10:49,050 upon your promise, it'll call the then callback. 219 00:10:49,050 --> 00:10:51,750 So I'm expecting it that it should 220 00:10:51,750 --> 00:10:54,780 call that, it should find it. 221 00:10:54,780 --> 00:10:58,500 And in here I say, I'm expecting the HTML to be hello. 222 00:10:58,500 --> 00:11:00,270 Whenever you've got a callback, 223 00:11:00,270 --> 00:11:02,940 you've gotta call the done function. 224 00:11:02,940 --> 00:11:04,560 We've seen this a few times before, 225 00:11:04,560 --> 00:11:06,360 to say it basically tells jest 226 00:11:06,360 --> 00:11:08,850 when is my callback completed? 227 00:11:08,850 --> 00:11:10,260 Now it's complete. 228 00:11:10,260 --> 00:11:11,850 It found hello. 229 00:11:11,850 --> 00:11:14,670 Yes, it did. Resolves. 230 00:11:14,670 --> 00:11:16,800 I can check that the content really is correct. 231 00:11:16,800 --> 00:11:19,620 And then I can say to jest that this test is now done. 232 00:11:19,620 --> 00:11:21,303 It can now go onto the next test. 233 00:11:22,380 --> 00:11:25,980 So when you call find by text, if it finds it, 234 00:11:25,980 --> 00:11:29,250 it'll resolve and it'll call your then callback. 235 00:11:29,250 --> 00:11:32,463 If it fails, it'll call your catch callback. 236 00:11:33,390 --> 00:11:36,240 So in this case, I'm expecting it to fail. 237 00:11:36,240 --> 00:11:37,590 Find this text. 238 00:11:37,590 --> 00:11:39,150 I'm hoping it fails. 239 00:11:39,150 --> 00:11:41,010 If it fails, it'll reject. 240 00:11:41,010 --> 00:11:43,500 In other words, it'll call my catch handler. 241 00:11:43,500 --> 00:11:46,230 Verify that it called the catch handler. 242 00:11:46,230 --> 00:11:48,990 I can check the kind of error that occurred. 243 00:11:48,990 --> 00:11:52,290 Okay, so this thing here that I've caught, 244 00:11:52,290 --> 00:11:54,303 is it an error object? 245 00:11:55,680 --> 00:11:57,030 Yes or no. 246 00:11:57,030 --> 00:11:58,800 So did it basically resolve-- 247 00:11:58,800 --> 00:12:01,140 Sorry, did it reject with an error, 248 00:12:01,140 --> 00:12:02,390 in which case we're done? 249 00:12:03,720 --> 00:12:07,050 So don't really feel any particular 250 00:12:07,050 --> 00:12:09,510 pressing need to use find by. 251 00:12:09,510 --> 00:12:12,120 Having to have a promise object here is kind of handy 252 00:12:12,120 --> 00:12:15,090 if you've got some kind of asynchronous check going on, 253 00:12:15,090 --> 00:12:18,300 but in general, it'd probably be the case that 254 00:12:18,300 --> 00:12:20,970 find by is a little bit over the top. 255 00:12:20,970 --> 00:12:23,850 Get by and query by are probably gonna be sufficient 256 00:12:23,850 --> 00:12:25,650 in most cases, but you never know. 257 00:12:25,650 --> 00:12:28,200 It is there in case you need it. 258 00:12:28,200 --> 00:12:33,200 So to run that test, run that test and it works. 259 00:12:33,420 --> 00:12:35,043 So to summarize, 260 00:12:36,420 --> 00:12:40,216 we have three different ways of doing a check. 261 00:12:40,216 --> 00:12:43,260 We can call the get by functions, 262 00:12:43,260 --> 00:12:45,450 which must return one match, 263 00:12:45,450 --> 00:12:47,073 otherwise it raises an error. 264 00:12:49,740 --> 00:12:53,580 There's the get by text using screen. 265 00:12:53,580 --> 00:12:57,930 And there's the get by text using the callback, okay? 266 00:12:57,930 --> 00:13:00,843 And then we had the find by functions. 267 00:13:01,680 --> 00:13:03,870 Let's look at query second. 268 00:13:03,870 --> 00:13:07,200 The query functions that return either the element, 269 00:13:07,200 --> 00:13:11,670 if it finds it, or null if it doesn't find it. 270 00:13:11,670 --> 00:13:15,120 And then the third family functions, the find by functions, 271 00:13:15,120 --> 00:13:17,820 where you tell it what you're looking for. 272 00:13:17,820 --> 00:13:20,520 It'll resolve if it finds it, 273 00:13:20,520 --> 00:13:22,590 and it'll call you a then handler. 274 00:13:22,590 --> 00:13:26,073 It'll reject and call you a catch handler if it doesn't.