diff --git a/files/en-us/glossary/google_chrome/index.md b/files/en-us/glossary/google_chrome/index.md index 8de6d95b3453efe..903a96b5b2fe6b9 100644 --- a/files/en-us/glossary/google_chrome/index.md +++ b/files/en-us/glossary/google_chrome/index.md @@ -6,7 +6,9 @@ page-type: glossary-definition {{GlossarySidebar}} -Google Chrome is a free Web {{glossary("browser")}} developed by Google. It's based on the [Chromium](https://www.chromium.org/) open source project. Some key differences are described on [BrowserStack](https://www.browserstack.com/guide/difference-between-chrome-and-chromium#toc5). Chrome supports its own layout called {{glossary("Blink")}}. Note that the iOS version of Chrome uses that platform's WebView, not Blink. +Google Chrome is a free Web {{glossary("browser")}} developed by Google, based on the [Chromium](https://www.chromium.org/) open source project. Some key differences are described in BrowserStack's [Chrome vs Chromium: Core Differences](https://www.browserstack.com/guide/difference-between-chrome-and-chromium) guide. + +Chrome also uses its own layout engine called {{glossary("Blink")}}, which is part of the Chromium project. Note that the iOS version of Chrome uses that platform's WebView, not Blink. ## See also diff --git a/files/en-us/learn/common_questions/tools_and_setup/what_software_do_i_need/index.md b/files/en-us/learn/common_questions/tools_and_setup/what_software_do_i_need/index.md index 67912ad1ea97140..3ade6486ad07ab2 100644 --- a/files/en-us/learn/common_questions/tools_and_setup/what_software_do_i_need/index.md +++ b/files/en-us/learn/common_questions/tools_and_setup/what_software_do_i_need/index.md @@ -251,17 +251,18 @@ Uploading files to a web server is a very important step while creating a websit -### Browsing websites +### Testing websites -As you already know, you need a web browser to view websites. There are [dozens](https://en.wikipedia.org/wiki/List_of_web_browsers) of browser options for your personal use, but when you're developing a website you should test it at least with the following major browsers, to make sure your site works for most people: +There are [many web browsers available](https://en.wikipedia.org/wiki/List_of_web_browsers). When you're developing a website you should test it at least with the following major browsers, to make sure your site works for most people: - [Mozilla Firefox](https://www.mozilla.org/en-US/firefox/new/) - [Google Chrome](https://www.google.com/chrome/) - [Apple Safari](https://www.apple.com/safari/) -If you're targeting a specific group (e.g., technical platform or country), you may have to test the site with additional browsers, like [Opera](https://www.opera.com/), [Konqueror](https://apps.kde.org/konqueror/). +If you're targeting a specific group (e.g., technical platform or country), you may have to test the site with additional browsers, like [Opera](https://www.opera.com/) or [Konqueror](https://apps.kde.org/konqueror/). + +Testing gets complicated because some browsers only run on certain operating systems. Notably, Apple Safari runs on iOS, iPadOS, and macOS. It's best to take advantage of services like [Browsershots](https://browsershots.org/) or [Browserstack](https://www.browserstack.com/). Browsershots creates screenshots of your website as it will look in various browsers. Browserstack gives you full remote access to virtual machines, so you can test your site in the most common environments and on different operating systems. Alternatively, you can set up your own virtual machines, but that takes some expertise. -Testing gets complicated because some browsers only run on certain operating systems. Notably, Apple Safari runs on iOS, iPadOS, and macOS. It's best to take advantage of services like [Browsershots](https://browsershots.org/) or [Browserstack](https://www.browserstack.com/). Browsershots furnishes screenshots of your website as it will look in various browsers. Browserstack gives you full remote access to virtual machines, so you can test your site in the most common environments and on different operating systems. Alternatively, you can set up your own virtual machines, but that takes some expertise. See [Strategies for carrying out testing: Putting together a testing lab](/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#putting_together_a_testing_lab) for more information. By all means run some tests on a real device, especially on real mobile devices. Mobile device simulation is a new, evolving technology and less reliable than desktop simulation. Mobile devices cost money, of course, so we suggest taking a look at the [Open Device Lab initiative](https://www.smashingmagazine.com/2016/11/worlds-best-open-device-labs/#odls-have-opened-doors-for-idls). You can also share devices if you want to test on many platforms without spending too much. diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-choices-sized.png b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-choices-sized.png index 89882f90d1fa0fb..29360a3039ae4bb 100644 Binary files a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-choices-sized.png and b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-choices-sized.png differ diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-device-sized.png b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-device-sized.png index faf51aba859d70d..9a0716d57e5070c 100644 Binary files a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-device-sized.png and b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-device-sized.png differ diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-menu-sized.png b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-menu-sized.png index c4274a0a8c386fa..9a287a71484ad23 100644 Binary files a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-menu-sized.png and b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/browserstack-test-menu-sized.png differ diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/index.md b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/index.md index d42dfb8c9d16584..3b095e3321c4fc7 100644 --- a/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/index.md +++ b/files/en-us/learn/tools_and_testing/cross_browser_testing/automated_testing/index.md @@ -6,7 +6,7 @@ page-type: learn-module-chapter {{LearnSidebar}}{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment", "Learn/Tools_and_testing/Cross_browser_testing")}} -Manually running tests on several browsers and devices, several times per day, can get tedious, and time-consuming. To handle this efficiently, you should become familiar with automation tools. In this article, we look at what is available, how to use task runners, and how to use the basics of commercial browser test automation apps such as LambdaTest, Sauce Labs, BrowserStack, and TestingBot. +Manually running tests on several browsers and devices, several times per day, can get tedious, and time-consuming. To handle this efficiently, you should become familiar with automation tools. In this article, we look at what is available, how to use task runners, and how to use the basics of commercial browser test automation apps such as Sauce Labs, BrowserStack, and TestingBot. @@ -46,7 +46,7 @@ As we said above, you can drastically speed up common tasks such as linting and ### Setting up Node and npm -Most tools these days are based on {{Glossary("Node.js")}}, so you'll need to install it from [nodejs.org](https://nodejs.org/): +Most tools these days are based on {{Glossary("Node.js")}}, so you'll need to install it from [nodejs.org](https://nodejs.org): 1. Download the installer for your system from the above site. (If you already have Node and npm installed, jump to point 4) 2. Install it like you would any other program. Note that Node comes with [Node Package Manager](https://www.npmjs.com/) (npm), which allows you to easily install packages, share your own packages with others, and run useful scripts on your projects. @@ -57,7 +57,7 @@ Most tools these days are based on {{Glossary("Node.js")}}, so you'll need to in npm -v ``` -4. If you've got Node/npm already installed, you should update them to their latest versions. To update Node, the most reliable way is to download and install an updated installer package from their website (see link above). To update npm, use the following command in your terminal: +4. If you've got Node/npm already installed, or installed them a while ago, you should update them to their latest versions. To update Node, the most reliable way is to download and install an updated installer package from their website (see link above). To update npm, use the following command in your terminal: ```bash npm install npm@latest -g @@ -339,39 +339,12 @@ There are many other task runners available. We certainly aren't trying to say t Now let's look at commercial third-party browser testing services and what they can do for us. -The basic premise with such applications is that the company that runs each one has a huge server farm that can run many different tests. When you use this service, you provide a URL of the page you want to test along with information, such as what browsers you want it tested in. The app then configures a new VM with the OS and browser you specified, and returns the test results in the form of screenshots, videos, log files, text, etc. +The basic premise with such applications is that the company that runs each one has a huge server farm that can run many different tests. When you use this service, you provide a URL of the page you want to test along with information, such as what browsers you want it tested in. The app then configures a new VM with the OS and browser you specified, and returns the test results in the form of screenshots, videos, log files, text, etc. This is very useful, and way more convenient than having to set up all the OS/browser combinations by yourself. You can then step up a gear, using an API to access functionality programmatically, which means that such apps can be combined with task runners, such as your own local Selenium environments and others, to create automated tests. > [!NOTE] -> There are other commercial browser testing systems available but in this article, we'll focus on LambdaTest, Sauce Labs, and BrowserStack. We're not saying that these are necessarily the best tools available, but they are good ones that are simple for beginners to get up and running with. - -### LambdaTest - -#### Getting started with LambdaTest - -1. Let's get started by [signing up on LambdaTest](https://accounts.lambdatest.com/register) for free. -2. Sign in. This should happen automatically after you verify your email address. - -> [!NOTE] -> Unlike other cloud-based cross browser testing service providers, LambdaTest offers a freemium account where you get lifetime access to their platform. The only difference between their premium and their freemium plan is on the amount of consumption. For automation testing through their Selenium Grid, LambdaTest offers 60 minutes per month of free testing. - -#### The basics: Manual tests - -Once you sign in to LambdaTest, you will be routed to the LambdaTest Dashboard. The dashboard will provide you details related to how many minutes you have consumed, how many concurrent sessions are running, your total number of tests to date, and more. - -1. To start off with manual testing you need to select the **"Real Time Testing"** tab from the left navigation menu. - ![LambdaTest Dashboard](lambdatest-dashboard.png) -2. As you click on the **Real Time Testing** you will be directed to a screen where you can choose the browser configuration, browser version, OS, and screen resolution with which you want to test your website. - ![Real Time Testing](mark-as-bug-1.png) -3. As you click on the Start button, a loading screen will appear, providing you with a VM (Virtual Machine) based on your configurations. Once loaded, you can perform live, interactive cross-browser testing with a website. - [![Mark as bug](mark-as-bug-2.png)](https://web.archive.org/web/20210608014707if_/https://www.lambdatest.com/support/docs/wp-content/uploads/2019/03/mark-as-bug-2.png) - If you notice an issue with the UI, then you can share it with your colleagues by capturing a screenshot of your VM with the screenshot button. You can also record a video of your test session by hitting the recorder button in your test session. -4. With the in-built image editor, highlight your screenshot before you push it to your colleagues.![Highlight a bug](mark-as-bug-3.png) -5. Using the mark as bug button you can push bugs to numerous third-party tools such as Jira, Asana, Trello, and more. That way you can log a bug directly from your test session on LambdaTest to your project management instance. Check out all the [third-party LambdaTest integrations](https://www.lambdatest.com/integrations). - -> [!NOTE] -> All the videos and images captured inside a test session are captured inside the gallery, test logs, and issue tracker at LambdaTest. +> There are other commercial browser testing systems available but in this article, we'll focus on Sauce Labs, BrowserStack, and TestingBot. We're not saying that these are necessarily the best tools available, but they are good ones that are simple for beginners to get up and running with. ### Sauce Labs @@ -457,95 +430,85 @@ We'll cover actually running automated Sauce Lab tests in the next article. #### Getting started with BrowserStack -Let's get started with a BrowserStack Trial. +To get started: 1. Create a [BrowserStack trial account](https://www.browserstack.com/users/sign_up). 2. Sign in. This should happen automatically after you verify your email address. -3. When you first sign in, you should be on the Live testing page; if not, click the _Live_ link in the top nav menu. -4. If you are on Firefox or Chrome, you'll be prompted to Install a browser extension in a dialog titled "Enable Local Testing" — click the _Install_ button to proceed. On other browsers you'll still be able to use some of the features (generally via Flash), but you might not get the full experience. +3. Click the _Live_ link in the top nav menu to go to Live Manual Testing. #### The basics: Manual tests -The BrowserStack Live dashboard allows you to choose what device and browser you want to test on — Platforms in the left column, devices on the right. When you mouse over or click on each device, you get a choice of browsers available on that device. +The BrowserStack Live dashboard allows you to choose what device and browser you want to test on — platforms on the left, devices on the right. Select a device to see the choice of browsers available on that device. ![Test Choices](browserstack-test-choices-sized.png) -Clicking on one of those browser icons will load up your choice of platform/device/browser — choose one now, and give it a try. +Clicking on one of those browser icons will load up your choice of platform, device, and browser — choose one now, and give it a try. ![Test Devices](browserstack-test-device-sized.png) -> [!NOTE] -> The blue device icon next to some of the mobile device choices signals that you will be testing on a real device; choices without that icon will be run on an emulator. - -You'll find that you can enter URLs into the address bar, and use the other controls like you'd expect on a real device. You can even do things like copy and paste from the device to your clipboard, scroll up and down by dragging with the mouse, or use appropriate gestures (e.g. pinch/zoom, two fingers to scroll) on the touchpads of supporting devices (e.g. MacBook). Note that not all features are available on all devices. +You can enter URLs into the address bar, scroll up and down by dragging with the mouse, and use appropriate gestures (for example, pinch/zoom, two fingers to scroll) on the touchpads of supporting devices like MacBooks. Not all features are available on all devices. You'll also see a menu that allows you to control the session. ![Test Menu](browserstack-test-menu-sized.png) -The features here are as follows: +The available features vary depending on what browser is loaded, and can include controls for: -- _Switch_ — Change to another platform/device/browser combination. -- Orientation (looks like a Reload icon) — Switch orientation between portrait and landscape. -- Fit to screen (looks like a full screen icon) — Fill the testing areas as much as possible with the device. -- Capture a bug (looks like a camera) — Takes a screenshot, then allows you to annotate and save it. -- Issue tracker (looks like a deck of cards) — View previously captured bugs/screenshots. -- Settings (cog icon) — Allows you to alter general settings for the session. -- Help (question mark) — Accesses help/support functions. -- _Devtools_ — Allows you to use your browser's devtools to directly debug or manipulate the page being shown in the test browser. This currently only works when testing the Safari browser on iOS devices. -- _Device info_ — Displays information about the testing device. -- _Features_ — Shows you what features the current configuration supports, e.g. copy to clipboard, gesture support, etc. -- _Stop_ — Ends the session. - -> [!NOTE] -> This is already very useful, and way more convenient than having to set up all these emulators and virtual machines by yourself. - -#### Other basic features - -If you go back to the main BrowserStack page, you'll find a couple of other useful basic features under the _More_ menu option: - -- _Responsive_: Enter a URL and press _Generate_, and BrowserStack will load that URL on multiple devices with different viewport sizes. Within each device you can further adjust settings like monitor size, to get a good idea of how your site's layout works across different form factors. -- _Screenshots_: Enter a URL, choose the browsers/devices/platforms you are interested in, then press _Generate screenshots_ — BrowserStack will take screenshots of your site in all those different browsers then make them available to you to view and download. +- Displaying information on the current browser +- Switching to other browsers +- Testing localhost URLs +- Setting zoom level and toggling orientation +- Saving and loading bookmarks +- Capturing/annotating screenshots and filing bug reports +- Accessing browser DevTools +- Changing reported location +- Throttling the network +- Accessing screenreaders #### Advanced: The BrowserStack API BrowserStack also has a [restful API](https://www.browserstack.com/docs/automate/api-reference/selenium/introduction) that allows you to programmatically retrieve details of your account plan, sessions, builds, etc. -It has several clients available to allow you to make calls to the API using your favorite environment, be it PHP, Java, Node.js, etc. - Let's have a brief look at how we'd access the API using Node.js. 1. First, set up a new npm project to test this out, as detailed in [Setting up Node and npm](#setting_up_node_and_npm). Use a different directory name than before, like `bstack-test` for example. -2. Create a new file inside your project root called `call_bstack.js`. give it the following contents: +2. Create a new file inside your project root called `call_bstack.js` and give it the following content: ```js - const request = require("request"); + const axios = require("axios"); const bsUser = "BROWSERSTACK_USERNAME"; const bsKey = "BROWSERSTACK_ACCESS_KEY"; const baseUrl = `https://${bsUser}:${bsKey}@www.browserstack.com/automate/`; function getPlanDetails() { - request({ uri: `${baseUrl}plan.json` }, (err, res, body) => { - console.log(JSON.parse(body)); + axios.get(`${baseUrl}plan.json`).then((response) => { + console.log(response.data); }); /* Response: { automate_plan: , + terminal_access: . parallel_sessions_running: , team_parallel_sessions_max_allowed: , parallel_sessions_max_allowed: , queued_sessions: , queued_sessions_max_allowed: } - */ + */ } getPlanDetails(); ``` -3. You'll need to fill in your BrowserStack username and API key in the indicated places. These can be retrieved from your [BrowserStack Account & Profile Details](https://www.browserstack.com/accounts/profile/details), under the Authentication & Security section. Fill these in now. -4. Make sure everything is saved, and run your file like so: +3. Replace the placeholders for BrowserStack username and access key with your actual values. These can be retrieved from your [BrowserStack Account & Profile Details](https://www.browserstack.com/accounts/profile/details), under the _Authentication & Security_ section. +4. Install the [axios](https://www.npmjs.com/package/axios) module we are using in the above code by running the following command in your terminal: + + ```bash + npm install axios + ``` + +5. Make sure your JavaScript file is saved, and run it by executing the following command in your terminal. You should see an object printed to the terminal containing your BrowserStack plan details. ```bash node call_bstack @@ -553,42 +516,52 @@ Let's have a brief look at how we'd access the API using Node.js. Below we've also provided some other ready-made functions you might find useful when working with the BrowserStack restful API. +This function returns summary details of all automated builds previously created (see the next article for [BrowserStack automated test details](/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment#browserstack)): + ```js function getBuilds() { - request({ uri: `${baseUrl}builds.json` }, (err, res, body) => { - console.log(JSON.parse(body)); + axios.get(`${baseUrl}builds.json`).then((response) => { + console.log(response.data); }); + // request({ uri: `${baseUrl}builds.json` }, (err, res, body) => { + // console.log(JSON.parse(body)); + // }); /* Response: [ { automation_build: { name: , + hashed_id: , duration: , status: , - hashed_id: + build_tag: , + public_url: } }, { automation_build: { name: , + hashed_id: , duration: , status: , - hashed_id: + build_tag: , + public_url: } }, // … ] */ } +``` + +This function returns details on the specific sessions for a particular build: +```js function getSessionsInBuild(build) { const buildId = build.automation_build.hashed_id; - request( - { uri: `${baseUrl}builds/${buildId}/sessions.json` }, - (err, res, body) => { - console.log(JSON.parse(body)); - }, - ); + axios.get(`${baseUrl}builds/${buildId}/sessions.json`).then((response) => { + console.log(response.data); + }); /* Response: [ { @@ -608,42 +581,31 @@ function getSessionsInBuild(build) { logs: , browser_url: , public_url: , + appium_logs_url: , video_url: , browser_console_logs_url: , - har_logs_url: + har_logs_url: , + selenium_logs_url: } }, { automation_session: { - name: , - duration: , - os: , - os_version: , - browser_version: , - browser: , - device: , - status: , - hashed_id: , - reason: , - build_name: , - project_name: , - logs: , - browser_url: , - public_url: , - video_url: , - browser_console_logs_url: , - har_logs_url: + // … } }, // … ] */ } +``` + +The following function returns the details for one particular session: +```js function getSessionDetails(session) { const sessionId = session.automation_session.hashed_id; - request({ uri: `${baseUrl}sessions/${sessionId}.json` }, (err, res, body) => { - console.log(JSON.parse(body)); + axios.get(`${baseUrl}sessions/${sessionId}.json`).then((response) => { + console.log(response.data); }); /* Response: { @@ -663,9 +625,11 @@ function getSessionDetails(session) { logs: , browser_url: , public_url: , + appium_logs_url: , video_url: , browser_console_logs_url: , - har_logs_url: + har_logs_url: , + selenium_logs_url: } } */ @@ -674,7 +638,7 @@ function getSessionDetails(session) { #### Advanced: Automated tests -We'll cover actually running automated BrowserStack tests in the next article. +We'll cover [running automated BrowserStack tests](/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment#browserstack) in the next article. ### TestingBot diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_automated_results.png b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_automated_results.png index 222bcf53e969435..758480219fcc9d8 100644 Binary files a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_automated_results.png and b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_automated_results.png differ diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_custom_results.png b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_custom_results.png index b37d2ba6c307f9b..ee41b9885a597ff 100644 Binary files a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_custom_results.png and b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/bstack_custom_results.png differ diff --git a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/index.md b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/index.md index 99591d13dcb96a5..358d63f5660149f 100644 --- a/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/index.md +++ b/files/en-us/learn/tools_and_testing/cross_browser_testing/your_own_automation_environment/index.md @@ -57,7 +57,7 @@ We will cover writing and running Selenium tests using Node.js, as it is quick a Next, you need to download the relevant drivers to allow WebDriver to control the browsers you want to test. You can find details of where to get them from on the [selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver) page (see the table in the first section.) Obviously, some of the browsers are OS-specific, but we're going to stick with Firefox and Chrome, as they are available across all the main OSes. -1. Download the latest [GeckoDriver](https://github.com/mozilla/geckodriver/releases/) (for Firefox) and [ChromeDriver](https://developer.chrome.com/docs/chromedriver/downloads) drivers. +1. Download the latest [GeckoDriver](https://github.com/mozilla/geckodriver/releases/) (for Firefox) and [ChromeDriver](https://googlechromelabs.github.io/chrome-for-testing/#stable) drivers. 2. Unpack them into somewhere fairly easy to navigate to, like the root of your home user directory. 3. Add the `chromedriver` and `geckodriver` driver's location to your system `PATH` variable. This should be an absolute path from the root of your hard disk, to the directory containing the drivers. For example, if we were using a macOS machine, our user name was bob, and we put our drivers in the root of our home folder, the path would be `/Users/bob`. @@ -66,35 +66,31 @@ Next, you need to download the relevant drivers to allow WebDriver to control th To set your `PATH` variable on a macOS system and on most Linux systems: -1. If you're not already using the `bash` shell (for example, on macOS systems, the default is the `zsh` shell, not `bash`), switch to the `bash` shell: - - ```bash - exec bash - ``` - -2. Open your `.bash_profile` (or `.bashrc`) file (if you can't see hidden files, you'll need to display them, see [Show/Hide hidden files in macOS](https://ianlunn.co.uk/articles/quickly-showhide-hidden-files-mac-os-x-mavericks/) or [Show hidden folders in Ubuntu](https://askubuntu.com/questions/470837/how-to-show-hidden-folders-in-file-manager-nautilus-on-ubuntu)). -3. Paste the following into the bottom of your file (updating the path as it actually is on your machine): +1. Open your `.zprofile` (or `.bash_profile` if your system uses `bash` shell) file. + > [!NOTE] + > If you can't see hidden files, you'll need to display them, see [Show/Hide hidden files in macOS](https://ianlunn.co.uk/articles/quickly-showhide-hidden-files-mac-os-x-mavericks/) or [Show hidden folders in Ubuntu](https://askubuntu.com/questions/470837/how-to-show-hidden-folders-in-file-manager-nautilus-on-ubuntu)). +2. Paste the following into the bottom of your file (updating the path as it actually is on your machine): ```bash #Add WebDriver browser drivers to PATH - export PATH=$PATH:/Users/bob ``` -4. Save and close this file, then restart your Terminal/command prompt to reapply your Bash configuration. -5. Check that your new paths are in the `PATH` variable by entering the following into your terminal: +3. Save and close this file, then restart your Terminal/command prompt to reapply your Bash configuration. +4. Check that your new paths are in the `PATH` variable by entering the following into your terminal: ```bash echo $PATH ``` -6. You should see it printed out in the terminal. + You should see it printed out in the terminal. -To set your `PATH` variable on Windows, follow the instructions at [How can I add a new folder to my system path?](https://www.itprotoday.com/) +> [!NOTE] +> To set your `PATH` variable on Windows, follow the instructions at [How can I add a new folder to my system path?](https://www.itprotoday.com/) -OK, let's try a quick test to make sure everything is working. +Let's try a quick test to make sure everything is working. -1. Create a new file inside your project directory called `google_test.js`: +1. Create a new file inside your project directory called `duck_test.js`: 2. Give it the following contents, then save it: ```js @@ -103,9 +99,12 @@ OK, let's try a quick test to make sure everything is working. (async function example() { const driver = await new Builder().forBrowser(Browser.FIREFOX).build(); try { - await driver.get("https://www.google.com/ncr"); + await driver.get("https://duckduckgo.com/"); await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN); - await driver.wait(until.titleIs("webdriver - Google Search"), 1000); + await driver.wait(until.titleIs("webdriver at DuckDuckGo"), 1000); + console.log("Test passed!"); + } catch (e) { + console.log(`Error: ${e}`); } finally { await driver.sleep(2000); // Delay long enough to see search page! await driver.quit(); @@ -119,39 +118,37 @@ OK, let's try a quick test to make sure everything is working. 3. In terminal, make sure you are inside your project folder, then enter the following command: ```bash - node google_test + node duck_test ``` -You should see an instance of Firefox automatically open up! Google should automatically be loaded in a tab, "webdriver" should be entered in the search box, and the search button will be clicked. WebDriver will then wait for 1 second; the document title is then accessed, and if it is "webdriver - Google Search", we will return a message to claim the test is passed. -We then wait four seconds, after which WebDriver will then close down the Firefox instance and stop. +You should see an instance of Firefox automatically open up! DuckDuckGo will automatically be loaded in a tab, "webdriver" will be entered in the search box, and the search button will be clicked. WebDriver will then wait for 1 second; the document title is then accessed, and if it is "webdriver at DuckDuckGo", we will return a message to state that the test is passed. + +We then wait 2 seconds, after which WebDriver will close down the Firefox instance and stop. ## Testing in multiple browsers at once There is also nothing to stop you running the test on multiple browsers simultaneously. Let's try this! -1. Create another new file inside your project directory called `google_test_multiple.js`. You can feel free to change the references to some of the other browsers we added, remove them, etc., depending on what browsers you have available to test on your operating system. You'll need to make sure you have the right browser drivers set up on your system. In terms of what string to use inside the `.forBrowser()` method for other browsers, see the [Browser enum](https://www.selenium.dev/selenium/docs/api/javascript/global.html#Browser) reference page. -2. Give it the following contents, then save it: +1. Create another new file inside your project directory called `duck_test_multiple.js`. You can feel free to change the references to some of the other browsers we added, remove them, etc., depending on what browsers you have available to test on your operating system. You'll need to make sure you have the right browser drivers set up on your system. In terms of what string to use inside the `.forBrowser()` method for other browsers, see the [Browser enum](https://www.selenium.dev/selenium/docs/api/javascript/global.html#Browser) reference page. +2. Give your file the following contents, then save it: ```js const { Builder, Browser, By, Key } = require("selenium-webdriver"); const driver_fx = new Builder().forBrowser(Browser.FIREFOX).build(); - const driver_chr = new Builder().forBrowser(Browser.CHROME).build(); async function searchTest(driver) { try { - await driver.get("http://www.google.com"); + await driver.get("https://duckduckgo.com/"); await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN); - await driver.sleep(2000).then(async () => { - await driver.getTitle().then(async (title) => { - if (title === "webdriver - Google Search") { - console.log("Test passed"); - } else { - console.log("Test failed"); - } - }); - }); + await driver.sleep(2000); + const title = await driver.getTitle(); + if (title === "webdriver at DuckDuckGo") { + console.log("Test passed"); + } else { + console.log("Test failed"); + } } finally { driver.quit(); } @@ -164,14 +161,17 @@ There is also nothing to stop you running the test on multiple browsers simultan 3. In terminal, make sure you are inside your project folder, then enter the following command: ```bash - node google_test_multiple + node duck_test_multiple ``` -4. If you are using a Mac and do decide to test Safari, you might get an error message along the lines of "Could not create a session: You must enable the 'Allow Remote Automation' option in Safari's Develop menu to control Safari via WebDriver." If you get this, follow the given instruction and try again. +> [!NOTE] +> If you are using a Mac and decide to test Safari, you might get an error message along the lines of "Could not create a session: You must enable the 'Allow Remote Automation' option in Safari's Develop menu to control Safari via WebDriver." If you get this, follow the given instruction and try again. +> +> You might get a message saying that you can't open a driver app because it was not downloaded from a verified source. If you get this, you can override that security setting just for that driver app. For example, on Mac, Ctrl + click on the app, choose _Open_, and choose _Open_ again from the resulting dialog box. -So here we've done the test as before, except that this time we've wrapped it inside a function, `searchTest()`. We've created new browser instances for multiple browsers, then passed each one to the function so the test is performed on all three browsers! +So here we've done the test as before, except that this time we've wrapped it inside a function, `searchTest()`. We've created new browser instances for multiple browsers, then passed each one to the function so the test is performed on all of them. -Fun huh? Let's move on, look at the basics of WebDriver syntax, in a bit more detail. +Let's move on and look at the basics of WebDriver syntax, in a bit more detail. ## WebDriver syntax crash course @@ -195,13 +195,13 @@ let driver = new Builder().forBrowser(Browser.FIREFOX).build(); Note that it is possible to set specific configuration options for browsers to be tested, for example you can set a specific version and OS to test in the `forBrowser()` method: ```js -let driver = new Builder().forBrowser(Browser.FIREFOX, "46", "MAC").build(); +let driver = new Builder().forBrowser(Browser.FIREFOX, "130", "MAC").build(); ``` You could also set these options using an environment variable, for example: ```bash -SELENIUM_BROWSER=firefox:46:MAC +SELENIUM_BROWSER=firefox:130:MAC ``` Let's create a new test to allow us to explore this code as we talk about it. Inside your selenium test project directory, create a new file called `quick_test.js`, and add the following code to it: @@ -214,6 +214,12 @@ const { Builder, Browser } = require("selenium-webdriver"); })(); ``` +You can test the example by entering the following command into your terminal: + +```bash +node quick_test +``` + ### Getting the document you want to test To load the page you actually want to test, you use the `get()` method of the driver instance you created earlier, for example: @@ -228,29 +234,25 @@ driver.get("http://www.google.com"); You can use any URL to point to your resource, including a `file://` URL to test a local document: ```js -driver.get( - "file:///Users/chrismills/git/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html", -); +driver.get("file:///Users/bob/git/examples/test_file.html"); ``` or ```js -driver.get("http://localhost:8888/fake-div-buttons.html"); +driver.get("http://localhost:8888/test_file.html"); ``` But it is better to use a remote server location so the code is more flexible — when you start using a remote server to run your tests (see later on), your code will break if you try to use local paths. -Update your `example()` function as follows: +Update your `example()` function as follows, replacing the placeholder path with a real local path to an HTML file on your computer, then try running it: ```js const { Builder, Browser } = require("selenium-webdriver"); (async function example() { const driver = await new Builder().forBrowser(Browser.FIREFOX).build(); - driver.get( - "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html", - ); + driver.get("file:///Users/bob/git/examples/test_file.html"); })(); ``` @@ -264,7 +266,7 @@ const element = driver.findElement(By.id("myElementId")); One of the most useful ways to find an element by CSS — the `By.css()` method allows you to select an element using a CSS selector. -Update your `example()` function now as follows: +Update your `example()` function now as follows, then run the example: ```js const { Builder, Browser, By } = require("selenium-webdriver"); @@ -280,7 +282,7 @@ const { Builder, Browser, By } = require("selenium-webdriver"); ### Testing your element -There are many ways to interact with your web documents and elements on them. You can see useful common examples starting at [Getting text values](https://www.selenium.dev/documentation/webdriver/elements/information/#text-content) on the WebDriver docs. +There are many ways to interact with your web documents and elements inside them. You can see useful common examples starting at [Getting text values](https://www.selenium.dev/documentation/webdriver/elements/information/#text-content) on the WebDriver docs. If we wanted to get the text inside our button, we could do this: @@ -290,7 +292,7 @@ button.getText().then((text) => { }); ``` -Add this to the bottom of the `example()` function now as shown below: +Add this to the bottom of the `example()` function now as shown below, then run it: ```js const { Builder, Browser, By } = require("selenium-webdriver"); @@ -310,15 +312,9 @@ const { Builder, Browser, By } = require("selenium-webdriver"); })(); ``` -Making sure you are inside your project directory, try running the test: - -```bash -node quick_test.js -``` - You should see the button's text label reported inside the console. -Let's do something a bit more useful. Replace the previous code entry with this line of code, `button.click();` as shown below: +Let's do something a bit more useful. Replace the previous code entry with `button.click();` as shown below: ```js const { Builder, Browser, By } = require("selenium-webdriver"); @@ -335,7 +331,7 @@ const { Builder, Browser, By } = require("selenium-webdriver"); })(); ``` -Try running your test again; the button will be clicked, and the `alert()` popup should appear. At least we know the button is working! +Try running your test again; the button will be clicked, and an `alert()` popup should appear. At least we know the button is working! You can interact with the popup too. Update the `example()` function as follows, and try testing it again: @@ -365,10 +361,10 @@ const { Builder, Browser, By, until } = require("selenium-webdriver"); })(); ``` -Next, let's try entering some text into one of the form elements. Update the `example()` function as follows and try running your test again: +Next, let's try entering some text into the form elements. Update the `example()` function as follows and try running your test again: ```js -const { Builder, Browser, By, until } = require("selenium-webdriver"); +const { Builder, Browser, By, Key } = require("selenium-webdriver"); (async function example() { const driver = await new Builder().forBrowser(Browser.FIREFOX).build(); @@ -377,121 +373,110 @@ const { Builder, Browser, By, until } = require("selenium-webdriver"); ); const input = driver.findElement(By.id("name")); - input.sendKeys("Filling in my form"); + input.sendKeys("Bob Smith"); - const button = driver.findElement(By.css("button:nth-of-type(1)")); + input.sendKeys(Key.TAB); - button.click(); - await driver.wait(until.alertIsPresent()); - - const alert = driver.switchTo().alert(); - - alert.getText().then((text) => { - console.log(`Alert text is '${text}'`); - }); - - alert.accept(); + const input2 = driver.findElement(By.id("age")); + input2.sendKeys("65"); })(); ``` -You can submit key presses that can't be represented by normal characters using properties of the `Key` object. For example, above we used this construct to tab out of the form input before submitting it: +You can submit key presses that can't be represented by normal characters using properties of the `Key` object. For example, above we used the following to tab between form inputs: ```js -driver.sleep(1000).then(() => { - driver.findElement(By.name("q")).sendKeys(Key.TAB); -}); +input.sendKeys(Key.TAB); ``` ### Waiting for something to complete There are times where you'll want to make WebDriver wait for something to complete before carrying on. For example if you load a new page, you'll want to wait for the page's DOM to finish loading before you try to interact with any of its elements, otherwise the test will likely fail. -In our `google_test.js` test for example, we included this block: +In our `duck_test_multiple.js` test for example, we included this line: ```js -driver.sleep(2000).then(() => { - driver.getTitle().then((title) => { - if (title === "webdriver - Google Search") { - console.log("Test passed"); - } else { - console.log("Test failed"); - } - }); -}); +await driver.sleep(2000); ``` -The `sleep()` method accepts a value that specifies the time to wait in milliseconds — the method returns a promise that resolves at the end of that time, at which point the code inside the `then()` executes. In this case we get the title of the current page with the `getTitle()` method, then return a pass or fail message depending on what its value is. +The `sleep()` method accepts a value that specifies the time to wait in milliseconds — the method returns a promise that resolves at the end of that time, at which point the code after it executes. We could add a `sleep()` method to our `quick_test.js` test too — try updating your `example()` function like this: ```js -const { Builder, Browser, By, until } = require("selenium-webdriver"); - -const driver = new Builder().forBrowser("firefox").build(); +const { Builder, Browser, By, Key } = require("selenium-webdriver"); (async function example() { - try { - driver.get( - "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html", - ); - - driver.sleep(2000).then(() => { - const input = driver.findElement(By.id("name")); - - input.sendKeys("Filling in my form"); - input.getAttribute("value").then((value) => { - if (value !== "") { - console.log("Form input editable"); - } - }); - }); - - const button = driver.findElement(By.css("button:nth-of-type(1)")); - - button.click(); - - await driver.wait(until.alertIsPresent()); - - const alert = driver.switchTo().alert(); + const driver = await new Builder().forBrowser(Browser.FIREFOX).build(); + driver.get( + "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html", + ); - alert.getText().then((text) => { - console.log(`Alert text is '${text}'`); + const input = driver.findElement(By.id("name")); + input.sendKeys("Bob Smith"); + + driver.sleep(1000).then(() => { + input.getAttribute("value").then((value) => { + if (value !== "") { + console.log("Form input filled out"); + } else { + console.log("Text could not be entered"); + } }); - - alert.accept(); - } finally { - await driver.sleep(4000); // Delay long enough to see search page! - driver.quit(); - } + }); })(); ``` -WebDriver will now wait for 2 seconds before filling in the form field. We then test whether its value got filled in (i.e. is not empty) by using `getAttribute()` to retrieve its `value` attribute value, and print a message to the console if it is not empty. +WebDriver will now fill out the first form field, wait for one second, then test whether its value got filled out (i.e., is not empty) by using `getAttribute()` to retrieve its `value` attribute value. It then prints a message to the console to report success/failure. > [!NOTE] > There is also a method called [`wait()`](https://www.selenium.dev/selenium/docs/api/javascript/WebDriver.html#wait), which repeatedly tests a condition for a certain length of time, and then carries on executing the code. This also makes use of the [util library](https://www.selenium.dev/selenium/docs/api/javascript/lib_until.js.html), which defines common conditions to use along with `wait()`. ### Shutting down drivers after use -After you've finished running a test, you should shut down any driver instances you've opened, to make sure that you don't end up with loads of rogue browser instances open on your machine! This is done using the `quit()` method. Call this on your driver instance when you are finished with it. Add this line to the bottom of your `quick_test.js` test now: +After you've finished running a test, you should shut down any driver instances you've opened, to make sure they don't continue to use resources unneccessarily. This is done using the `driver.quit()` method. Update `quick_test.js` as follows: ```js -driver.quit(); +const { Builder, Browser, By, Key } = require("selenium-webdriver"); + +(async function example() { + const driver = await new Builder().forBrowser(Browser.FIREFOX).build(); + driver.get( + "https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html", + ); + + const input = driver.findElement(By.id("name")); + input.sendKeys("Bob Smith"); + + driver.sleep(1000).then(() => { + input + .getAttribute("value") + .then((value) => { + if (value !== "") { + console.log("Form input filled out"); + } else { + console.log("Text could not be entered"); + } + }) + .finally(() => { + driver.quit(); + }); + }); +})(); ``` -When you run it, you should now see the test execute and the browser instance shut down again after the test is complete. This is useful for not cluttering up your computer with loads of browser instances, especially if you have so many that it is causing the computer to slow down. +Now when you run it, you should now see the test execute and the browser instance shut down again after the test is complete. ## Test best practices There has been a lot written about best practices for writing tests. You can find some good background information at [Test Practices](https://www.selenium.dev/documentation/test_practices/). In general, you should make sure that your tests are: 1. Using good locator strategies: When you are [Interacting with the document](#interacting_with_the_document), make sure that you use locators and page objects that are unlikely to change — if you have a testable element that you want to perform a test on, make sure that it has a stable ID, or position on the page that can be selected using a CSS selector, which isn't going to just change with the next site iteration. You want to make your tests as non-brittle as possible, i.e. they won't just break when something changes. -2. Write atomic tests: Each test should test one thing only, making it easy to keep track of what test file is testing which criterion. As an example, the `google_test.js` test we looked at above is pretty good, as it just tests a single thing — whether the title of a search results page is set correctly. We could work on giving it a better name so it is easier to work out what it does if we add more google tests. Perhaps `results_page_title_set_correctly.js` would be slightly better? +2. Write atomic tests: Each test should test one thing only, making it easy to keep track of what test file is testing which criterion. The `duck_test.js` test we looked at above is pretty good, as it just tests a single thing — whether the title of a search results page is set correctly. We could work on giving it a better name so it is easier to work out what it does if we add more tests. Perhaps `results_page_title_set_correctly.js` would be slightly better? 3. Write autonomous tests: Each test should work on it's own, and not depend on other tests to work. -In addition, we should mention test results/reporting — we've been reporting results in our above examples using simple `console.log()` statements, but this is all done in JavaScript, so you can use whatever test running and reporting system you want, be it [Mocha](https://mochajs.org/), [Chai](https://www.chaijs.com/), or some other tool. +In addition, we should mention test results/reporting — we've been reporting results in our above examples using simple `console.log()` statements, but this is all done in JavaScript, so you can use whatever test running and reporting system you want, be it [Mocha](https://mochajs.org/), [Chai](https://www.chaijs.com/), or some other tool. Lets work through a quick example: -1. For example, try making a local copy of our [`mocha_test.js`](https://github.com/mdn/learning-area/blob/main/tools-testing/cross-browser-testing/selenium/mocha_test.js) example inside your project directory. Put it inside a subfolder called `test`. This example uses a long chain of promises to run all the steps required in our test — the promise-based methods WebDriver uses need to resolve for it to work properly. +1. Make a local copy of our [`mocha_test.js`](https://github.com/mdn/learning-area/blob/main/tools-testing/cross-browser-testing/selenium/mocha_test.js) example inside your project directory. Put it inside a subfolder called `test`. This example uses a long chain of promises to run all the steps required in our test — the promise-based methods WebDriver uses need to resolve for it to work properly. 2. Install the mocha test harness by running the following command inside your project directory: ```bash @@ -512,108 +497,15 @@ In addition, we should mention test results/reporting — we've been reporting r It turns out that running tests on remote servers isn't that much more difficult than running them locally. You just need to create your driver instance, but with a few more features specified, including the capabilities of the browser you want to test on, the address of the server, and the user credentials you need (if any) to access it. -### LambdaTest - -Getting Selenium tests to run remotely on LambdaTest is very simple. The code you need should follow the pattern seen below. - -Let's write an example: - -1. Inside your project directory, create a new file called `lambdatest_google_test.js` -2. Give it the following contents: - - ```js - const { By, Builder } = require("selenium-webdriver"); - - // username: Username can be found at automation dashboard - const USERNAME = "{username}"; - - // AccessKey: AccessKey can be generated from automation dashboard or profile section - const KEY = "{accessKey}"; - - // gridUrl: gridUrl can be found at automation dashboard - const GRID_HOST = "hub.lambdatest.com/wd/hub"; - - function searchTextOnGoogle() { - // Setup Input capabilities - const capabilities = { - platform: "windows 10", - browserName: "chrome", - version: "67.0", - resolution: "1280x800", - network: true, - visual: true, - console: true, - video: true, - name: "Test 1", // name of the test - build: "NodeJS build", // name of the build - }; - - // URL: https://{username}:{accessToken}@hub.lambdatest.com/wd/hub - const gridUrl = `https://${USERNAME}:${KEY}@${GRID_HOST}`; - - // setup and build selenium driver object - const driver = new Builder() - .usingServer(gridUrl) - .withCapabilities(capabilities) - .build(); - - // navigate to a URL, search for a text and get title of page - driver.get("https://www.google.com/ncr").then(function () { - driver - .findElement(By.name("q")) - .sendKeys("LambdaTest\n") - .then(function () { - driver.getTitle().then((title) => { - setTimeout(() => { - if (title === "LambdaTest - Google Search") { - driver.executeScript("lambda-status=passed"); - } else { - driver.executeScript("lambda-status=failed"); - } - driver.quit(); - }, 5000); - }); - }); - }); - } - - searchTextOnGoogle(); - ``` - -3. Visit your [LambdaTest automation dashboard](https://www.lambdatest.com/selenium-automation), to fetch your LambdaTest's username and access key by clicking on the **key** icon on the top-right(see _Username and Access Keys_). Replace the `{username}` and `{accessKey}` placeholders in the code with your actual user name and access key values (and make sure you keep them secure). -4. Run the below command in your terminal to execute your test: - - ```bash - node lambdatest_google_test - ``` - - The test will be sent to LambdaTest, and the output of your test will be reflected on your LambdaTest console. - If you wish to extract these results for reporting purpose from LambdaTest platform then you can do so by using [LambdaTest restful API](https://www.lambdatest.com/blog/lambdatest-launches-api-for-selenium-automation/). - -5. Now if you go to your [LambdaTest Automation dashboard](https://accounts.lambdatest.com/dashboard), you'll see your test listed; from here you'll be able to see videos, screenshots, and other such data. - You will also see a status of **passed** or **failed** instead of **completed**, because of the `if` or `else` blocks of code. - - [![LambdaTest Automation Dashboard](automation-logs-1.jpg)](https://www.lambdatest.com/blog/wp-content/uploads/2019/02/Automation-logs-1.jpg) - You can retrieve network, command, exception, and Selenium logs for every test within your test build. You will also find a video recording of your Selenium script execution. - -> [!NOTE] -> The _HELP_ button on LambdaTest Automation Dashboard will provide you with an ample amount of information to help you get started with LambdaTest automation. You can also follow our documentation about [running first Selenium script in Node JS](https://www.lambdatest.com/support/docs/quick-guide-to-run-node-js-tests-on-lambdatest-selenium-grid/). - -> [!NOTE] -> If you don't want to write out the capabilities objects for your tests by hand, you can generate them using the [Selenium Desired Capabilities Generator](https://www.lambdatest.com/capabilities-generator/). - ### BrowserStack -Getting Selenium tests to run remotely on BrowserStack is easy. The code you need should follow the pattern seen below. - -Let's write an example: +Let's create an example to show how to get a Selenium test running remotely on BrowserStack: -1. Inside your project directory, create a new file called `bstack_google_test.js`. +1. Inside your project directory, create a new file called `bstack_duck_test.js`. 2. Give it the following contents: ```js const { Builder, By, Key } = require("selenium-webdriver"); - const request = require("request"); // Input capabilities const capabilities = { @@ -636,11 +528,11 @@ Let's write an example: (async function bStackGoogleTest() { try { - await driver.get("https://www.google.com/"); + await driver.get("https://duckduckgo.com/"); await driver.findElement(By.name("q")).sendKeys("webdriver", Key.RETURN); await driver.sleep(2000); const title = await driver.getTitle(); - if (title === "webdriver - Google Search") { + if (title === "webdriver at DuckDuckGo") { console.log("Test passed"); } else { console.log("Test failed"); @@ -652,8 +544,9 @@ Let's write an example: })(); ``` -3. From your [BrowserStack Account - Summary](https://www.browserstack.com/accounts/profile/details), get your user name and access key (see _Username and Access Keys_). Replace the `YOUR-USER-NAME` and `YOUR-ACCESS-KEY` placeholders in the code with your actual user name and access key values (and make sure you keep them secure). -4. Run your test with the following command: +3. From your BrowserStack [Account & Profile details page](https://www.browserstack.com/accounts/profile/details), get your user name and access key (see _Username and Access Keys_). +4. Replace the `YOUR-USER-NAME` and `YOUR-ACCESS-KEY` placeholders in the code with your actual user name and access key values (and make sure to keep them secure). +5. Run your test with the following command: ```bash node bstack_google_test @@ -661,92 +554,75 @@ Let's write an example: The test will be sent to BrowserStack, and the test result will be returned to your console. This shows the importance of including some kind of result reporting mechanism! -5. Now if you go back to the [BrowserStack automation dashboard](https://www.browserstack.com/automate) page, you'll see your test listed: +6. Now if you go back to the [BrowserStack Automate dashboard](https://automate.browserstack.com/dashboard/), you'll see your test listed, with details including a video recording of the test, and multiple detailed logs of information pertaining to it: ![BrowserStack automated results](bstack_automated_results.png) -If you click on the link for your test, you'll get to a new screen where you will be able to see a video recording of the test, and multiple detailed logs of information pertaining to it. - -> [!NOTE] -> The _Resources_ menu option on the Browserstack automation dashboard contains a wealth of useful information on using it to run automated tests. See [Node JS Documentation for writing automate test scripts in Node JS](https://www.browserstack.com/docs/automate/selenium/getting-started/nodejs) for the node-specific information. Explore the docs to find out all the useful things BrowserStack can do. - > [!NOTE] -> If you don't want to write out the capabilities objects for your tests by hand, you can generate them using the generators embedded in the docs. See [Run your first test](https://www.browserstack.com/docs/automate/selenium/getting-started/nodejs#run-your-first-test). +> The _Resources_ menu option on the Browserstack automation dashboard contains a wealth of useful information on using it to run automated tests. See [Selenium with NodeJS](https://www.browserstack.com/docs/automate/selenium/getting-started/nodejs) for node-specific information. -#### Filling in BrowserStack test details programmatically +#### Filling out BrowserStack test details programmatically -You can use the BrowserStack REST API and some other capabilities to annotate your test with more details, such as whether it passed, why it passed, what project the test is part of, etc. BrowserStack doesn't know these details by default! +You can use the BrowserStack REST API and some other capabilities to annotate your test with more details, such as whether it passed, why it passed, what project the test is part of, etc. BrowserStack doesn't know these details by default. -Let's update our `bstack_google_test.js` demo, to show how these features work: +Let's update our `bstack_duck_test.js` demo, to show how these features work: -1. Install the request module by running the following command inside your project directory: +1. Install the [axios](https://www.npmjs.com/package/axios) module by running the following command inside your project directory: ```js - npm install request + npm install axios ``` -2. Then, we'll need to import the node request module, so we can use it to send requests to the REST API. Add the following line at the very top of your code: +2. Import the axios module so we can use it to send requests to the BrowserStack REST API. Add the following line at the very top of your code: ```js - const request = require("request"); + const axios = require("axios"); ``` 3. Now we'll update our `capabilities` object to include a project name — add the following line before the closing curly brace, remembering to add a comma at the end of the previous line (you can vary the build and project names to organize the tests in different windows in the BrowserStack automation dashboard): ```js - 'project' : 'Google test 2' + project: "DuckDuckGo test 2"; ``` -4. Next we need to access the `sessionId` of the current session, so we know where to send the request (the ID is included in the request URL, as you'll see later). Include the following lines just below the block that creates the `driver` object (`let driver …`) : +4. Next we'll retrieve the `sessionId` of the current session, and use it (along with your `userName` and `accessKey`) to assemble the URL to send requests to, to update the BrowserStack data. Include the following lines just below the block that creates the `driver` object (which starts with `const driver = new Builder()`) : ```js let sessionId; + let bstackURL; driver.session_.then((sessionData) => { sessionId = sessionData.id_; + bstackURL = `https://${capabilities["bstack:options"].userName}:${capabilities["bstack:options"].accessKey}@www.browserstack.com/automate/sessions/${sessionId}.json`; }); ``` -5. Finally, update the `driver.sleep(2000)` block near the bottom of the code to add REST API calls (again, replace the `YOUR-USER-NAME` and `YOUR-ACCESS-KEY` placeholders in the code with your actual user name and access key values): +5. Finally, update the `if ... else` block near the bottom of the code to send appropriate API calls to BrowserStack depending on whether the test passed or failed: ```js - driver.sleep(2000).then(() => { - driver.getTitle().then((title) => { - if (title === "webdriver - Google Search") { - console.log("Test passed"); - request({ - uri: `https://YOUR-USER-NAME:YOUR-ACCESS-KEY@www.browserstack.com/automate/sessions/${sessionId}.json`, - method: "PUT", - form: { - status: "passed", - reason: "Google results showed correct title", - }, - }); - } else { - console.log("Test failed"); - request({ - uri: `https://YOUR-USER-NAME:YOUR-ACCESS-KEY@www.browserstack.com/automate/sessions/${sessionId}.json`, - method: "PUT", - form: { - status: "failed", - reason: "Google results showed wrong title", - }, - }); - } + if (title === "webdriver at DuckDuckGo") { + console.log("Test passed"); + axios.put(bstackURL, { + status: "passed", + reason: "DuckDuckGo results showed correct title", }); - }); + } else { + console.log("Test failed"); + axios.put(bstackURL, { + status: "failed", + reason: "DuckDuckGo results showed wrong title", + }); + } ``` -These are fairly intuitive — once the test completes, we send an API call to BrowserStack to update the test with a passed or failed status, and a reason for the result. +Once the test completes, we send an API call to BrowserStack to update the test with a passed or failed status, and a reason for the result. -If you now go back to your [BrowserStack automation dashboard](https://live.browserstack.com/dashboard) page, you should see your test session available, as before, but with the updated data attached to it: +If you now go back to your [BrowserStack Automate dashboard](https://automate.browserstack.com/dashboard/), you should see your test session as before, but with your custom data attached to it. It shows a status of "PASSED", and the REST API reported reason for the pass: ![BrowserStack Custom Results](bstack_custom_results.png) ### Sauce Labs -Getting Selenium tests to run remotely on Sauce Labs is also very simple, and very similar to BrowserStack albeit with a few syntactic differences. The code you need should follow the pattern seen below. - -Let's write an example: +Let's look at an example that demonstrates getting Selenium tests to run remotely on Sauce Labs: 1. Inside your project directory, create a new file called `sauce_google_test.js`. 2. Give it the following contents: