WEBVTT 1 00:00:01.000 --> 00:00:02.890 Hi guys and welcome back. 2 00:00:02.890 --> 00:00:04.030 In this video we're quickly going 3 00:00:04.030 --> 00:00:07.470 to talk about two different types of wait. 4 00:00:07.470 --> 00:00:11.100 You've got explicit waits and implicit waits. 5 00:00:11.100 --> 00:00:12.410 We're going to be using these 6 00:00:12.410 --> 00:00:16.180 when JavaScript is taking longer to run than our code, 7 00:00:16.180 --> 00:00:17.013 and that would mean that 8 00:00:17.013 --> 00:00:19.780 our code would be faster than the JavaScript 9 00:00:19.780 --> 00:00:21.680 and that can cause a series of issues. 10 00:00:21.680 --> 00:00:24.010 For example, if the JavaScript is responsible 11 00:00:24.010 --> 00:00:26.240 for changing an element on the page 12 00:00:26.240 --> 00:00:28.450 and your code tries to access that element 13 00:00:28.450 --> 00:00:31.080 before the JavaScript runs then you're gonna have a problem 14 00:00:31.080 --> 00:00:32.780 because the element's not gonna be there. 15 00:00:32.780 --> 00:00:34.810 That sort of stuff is the, 16 00:00:34.810 --> 00:00:37.240 on occasions when you wanna use waits. 17 00:00:37.240 --> 00:00:39.200 An explicit wait, as you can see here, 18 00:00:39.200 --> 00:00:40.240 is very straightforward. 19 00:00:40.240 --> 00:00:42.680 You import the time module from Python, 20 00:00:42.680 --> 00:00:45.130 that's a built-in you don't need to instal it, 21 00:00:45.130 --> 00:00:46.820 and you do time.sleep, 22 00:00:46.820 --> 00:00:49.330 and that's gonna sleep for five seconds. 23 00:00:49.330 --> 00:00:50.590 You can use this in Selenium, 24 00:00:50.590 --> 00:00:53.621 you can use it anywhere else in your Python code, 25 00:00:53.621 --> 00:00:56.690 and it can be quite helpful but it's also a bit limited 26 00:00:56.690 --> 00:00:59.940 because if the element appears after one second 27 00:00:59.940 --> 00:01:02.570 then you've got four seconds of waste 28 00:01:02.570 --> 00:01:04.750 and if the element appears after ten seconds 29 00:01:04.750 --> 00:01:06.580 then this is not enough. 30 00:01:06.580 --> 00:01:09.460 And sometimes JavaScript takes longer to run, 31 00:01:09.460 --> 00:01:11.590 other times it takes less time to run 32 00:01:11.590 --> 00:01:14.763 so it's not ideal to do something like this. 33 00:01:15.780 --> 00:01:17.650 The other option for explicit waits is 34 00:01:17.650 --> 00:01:18.960 to do something like this. 35 00:01:18.960 --> 00:01:20.520 I know the code looks a bit complicated, 36 00:01:20.520 --> 00:01:23.520 we've not seen it before but don't worry too much. 37 00:01:23.520 --> 00:01:26.100 To do an explicit wait you need to import three things. 38 00:01:26.100 --> 00:01:28.000 You need to import By, 39 00:01:28.000 --> 00:01:31.891 you need to import expected_conditions and WebDriverWait. 40 00:01:31.891 --> 00:01:34.800 Then what you do is you use WebDriverWait, 41 00:01:34.800 --> 00:01:37.260 you give it the browser that you wanna use 42 00:01:37.260 --> 00:01:39.610 and how long to wait up to. 43 00:01:39.610 --> 00:01:43.860 So this code here is going to wait up to 10 seconds, 44 00:01:43.860 --> 00:01:47.350 unless the condition that we say happens. 45 00:01:47.350 --> 00:01:50.090 So when the condition happens the wait ends. 46 00:01:50.090 --> 00:01:53.663 So this is essentially a wait until but it can end early. 47 00:01:54.670 --> 00:01:55.839 The condition is, 48 00:01:55.839 --> 00:01:59.686 expected_conditions.presence_of_element_located. 49 00:01:59.686 --> 00:02:01.490 And this is a way of telling Selenium 50 00:02:01.490 --> 00:02:04.890 to wait until an element exists in the page. 51 00:02:04.890 --> 00:02:06.500 The element doesn't have to be visible, 52 00:02:06.500 --> 00:02:09.000 it just has to be there in the page. 53 00:02:09.000 --> 00:02:11.740 So these two lines of code are telling the browser 54 00:02:11.740 --> 00:02:13.910 to wait up to 10 seconds, 55 00:02:13.910 --> 00:02:17.740 unless an element appears on the page. 56 00:02:17.740 --> 00:02:19.190 And the element that has to appear on the page 57 00:02:19.190 --> 00:02:23.393 is the final line here line seven which is this tuple. 58 00:02:23.393 --> 00:02:28.393 A tuple of selector type and selector. 59 00:02:28.940 --> 00:02:33.240 Up 'til now we've been using CSS selectors as our selectors, 60 00:02:33.240 --> 00:02:35.710 but for the expected conditions module, 61 00:02:35.710 --> 00:02:37.850 you have to give it the selector type. 62 00:02:37.850 --> 00:02:40.460 So that means we give it a tuple that says 63 00:02:40.460 --> 00:02:45.460 By.CSS_SELECTOR and the locator. 64 00:02:47.720 --> 00:02:50.470 Here's how you use the By class. 65 00:02:50.470 --> 00:02:53.580 Up 'til now we've been using something like line three, 66 00:02:53.580 --> 00:02:57.605 TAG_DROPDOWN equal select#tag. 67 00:02:57.605 --> 00:03:01.440 That means we wanna access a select element in the HTML 68 00:03:01.440 --> 00:03:04.390 and the ID of the element is tag. 69 00:03:04.390 --> 00:03:07.320 Then when we run code like in line number eight, 70 00:03:07.320 --> 00:03:10.570 we do self.browser.find_element_by_css_selector 71 00:03:10.570 --> 00:03:12.570 and we pass in that stream. 72 00:03:12.570 --> 00:03:16.480 However, you can do find element instead, 73 00:03:16.480 --> 00:03:17.800 only that you have to pass it 74 00:03:17.800 --> 00:03:20.050 what type of selector you wanna use. 75 00:03:20.050 --> 00:03:22.920 So here we're gonna do self.browser.find_element 76 00:03:22.920 --> 00:03:25.310 and we pass in By.CSS_SELECTOR 77 00:03:26.270 --> 00:03:28.523 and then the string as the second argument. 78 00:03:29.540 --> 00:03:32.530 That means that we can then use other types of selectors 79 00:03:32.530 --> 00:03:33.520 if we want. 80 00:03:33.520 --> 00:03:35.900 So here's how you could do that if you wanted to organise 81 00:03:35.900 --> 00:03:37.250 your selectors in this way. 82 00:03:38.320 --> 00:03:40.680 Imagine you've got a selector like in line number four 83 00:03:40.680 --> 00:03:44.080 that says By.ID, "tag". 84 00:03:44.080 --> 00:03:46.760 Now this is how we define a tuple in Python, 85 00:03:46.760 --> 00:03:51.190 so JUST_ID is a tuple of two values, 86 00:03:51.190 --> 00:03:53.490 By.ID and tag. 87 00:03:53.490 --> 00:03:55.230 And here's how you can use them. 88 00:03:55.230 --> 00:03:56.970 You can do something like line 11, 89 00:03:56.970 --> 00:03:59.200 self.browser.find_element_by_id 90 00:03:59.200 --> 00:04:01.450 and you can pass in the string directly. 91 00:04:01.450 --> 00:04:03.110 In that cause you would not need 92 00:04:03.110 --> 00:04:05.700 to define just ID as a tuple, 93 00:04:05.700 --> 00:04:07.763 you could just define it as the ID. 94 00:04:08.910 --> 00:04:11.030 You could do something like line number 12, 95 00:04:11.030 --> 00:04:13.600 which is self.browser.find_element 96 00:04:13.600 --> 00:04:17.350 and then you pass By.ID and the string. 97 00:04:17.350 --> 00:04:19.110 And finally, and this is actually 98 00:04:19.110 --> 00:04:21.840 my preferred way of doing things in Selenium, 99 00:04:21.840 --> 00:04:24.040 is to do something like line 13. 100 00:04:24.040 --> 00:04:27.400 You define your locators as in line four, 101 00:04:27.400 --> 00:04:31.030 and then you do like in line 13 self.browser.find_element, 102 00:04:31.030 --> 00:04:35.480 and you pass in the two values of selector as arguments, 103 00:04:35.480 --> 00:04:37.710 and that's why we use the asterisk. 104 00:04:37.710 --> 00:04:40.220 This is essentially argument unpacking. 105 00:04:40.220 --> 00:04:45.000 So we say asterisk JUST_ID and that passes By.ID and tag 106 00:04:45.000 --> 00:04:47.240 as the two values as the two arguments 107 00:04:47.240 --> 00:04:49.380 to the find element method. 108 00:04:49.380 --> 00:04:52.370 And what that allows you to do is to very easily 109 00:04:52.370 --> 00:04:54.700 and very concisely define your selectors 110 00:04:54.700 --> 00:04:57.730 while also being explicit in what they are for 111 00:04:57.730 --> 00:05:00.310 so you don't have to assume that they're all CSS selectors. 112 00:05:00.310 --> 00:05:04.390 You can use say By CSS selector and then they tag dropdown 113 00:05:04.390 --> 00:05:06.840 or By.ID and then the tag. 114 00:05:06.840 --> 00:05:08.650 In our project we've not done this 115 00:05:08.650 --> 00:05:11.510 because I felt it added a little bit of complexity, 116 00:05:11.510 --> 00:05:13.890 but nonetheless it is my preferred way when 117 00:05:13.890 --> 00:05:15.893 I'm working on a larger project. 118 00:05:18.290 --> 00:05:21.410 So other things you can use with the By class, 119 00:05:21.410 --> 00:05:24.446 you can do By ID, XPATH, LINK_TEXT 120 00:05:24.446 --> 00:05:27.310 so you can actually search for links, 121 00:05:27.310 --> 00:05:29.740 you can do PARTIAL_LINK_TEXT, you can do NAME, 122 00:05:29.740 --> 00:05:30.773 TAG_NAME, CLASS_NAME and CSS_SELECTOR. 123 00:05:32.270 --> 00:05:33.840 So more information on all this 124 00:05:33.840 --> 00:05:36.060 is linked in the resources section of the lecture 125 00:05:36.060 --> 00:05:38.790 so feel free to take a look at the official documentation 126 00:05:38.790 --> 00:05:41.660 that I've put in there if you want more information on this. 127 00:05:41.660 --> 00:05:44.430 Finally we've got implicit waits. 128 00:05:44.430 --> 00:05:47.750 An implicit wait is defined at the very start of 129 00:05:47.750 --> 00:05:49.120 your Selenium code. 130 00:05:49.120 --> 00:05:52.710 So just after you create your ChromeDriver or your browser, 131 00:05:52.710 --> 00:05:57.040 you can say driver.implicitly_wait and then a number. 132 00:05:57.040 --> 00:05:58.571 And what this does is whenever 133 00:05:58.571 --> 00:06:02.160 you try to find an element and it's not there, 134 00:06:02.160 --> 00:06:05.210 the browser will wait up to 10 seconds in this case 135 00:06:05.210 --> 00:06:08.482 by checking continuously until the element appears. 136 00:06:08.482 --> 00:06:10.512 I do not recommend doing this, 137 00:06:10.512 --> 00:06:14.200 although it's much simpler it's kinda obscure, 138 00:06:14.200 --> 00:06:15.950 and then when you're looking at your code it's not clear 139 00:06:15.950 --> 00:06:18.550 that it's gonna wait up to 10 seconds every time. 140 00:06:18.550 --> 00:06:22.380 And also it can hide problems. 141 00:06:22.380 --> 00:06:25.730 If your code is always waiting 10 seconds for everything, 142 00:06:25.730 --> 00:06:27.910 it probably means something's wrong with your application. 143 00:06:27.910 --> 00:06:31.240 So usually you want to avoid implicit waits. 144 00:06:31.240 --> 00:06:32.770 However, they do exist, 145 00:06:32.770 --> 00:06:34.970 they are in the official documentation, 146 00:06:34.970 --> 00:06:37.840 you can use them and you should probably know about them if 147 00:06:37.840 --> 00:06:40.970 you want to apply for a Selenium-based job. 148 00:06:40.970 --> 00:06:42.330 Thanks for joining me in this video, 149 00:06:42.330 --> 00:06:43.640 let's jump into the code, 150 00:06:43.640 --> 00:06:45.263 so I'll see you in the next one.