{"id":14788,"date":"2022-02-23T20:06:28","date_gmt":"2022-02-23T20:06:28","guid":{"rendered":"http:\/\/abstracta.us\/blog\/?p=14788"},"modified":"2025-05-05T21:25:20","modified_gmt":"2025-05-05T21:25:20","slug":"selenium-ide","status":"publish","type":"post","link":"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/","title":{"rendered":"Selenium IDE"},"content":{"rendered":"\n<p>The original Selenium IDE was a well known plugin for Firefox which helped in the tests creation as a record &amp; playback tool, however as it was no longer supported back in 2017 by the then released&nbsp; Firefox version, it unfortunately ceased to exist. In spite of this, in recent years a new Selenium IDE has been released and revamped by Applitools with many advancements over its predecessor, to name a few:<\/p>\n\n\n\n<ul><li>Support for Chrome, Firefox, MS Edge<\/li><li>Smart locators<\/li><li>Control flow statements such as conditionals and loops<\/li><li>Automatic waits<\/li><li>Supports embedded JavaScript<\/li><li>Debugger with breakpoints<\/li><li>Code exports<\/li><li>Parallel execution with Selenium side runner<\/li><li>Create and insert community plugins<\/li><\/ul>\n\n\n\n<p>Let\u2019s take a look into some of them.<\/p>\n\n\n\n<ul><li><strong>Fallback Locators<\/strong><\/li><\/ul>\n\n\n\n<p><strong>\t<\/strong>During the recording the IDE automatically stores different selectors for the elements it interacts with along the way, so in case that the primary selector cannot be found, after an automatic wait time, the mechanism will resort to a secondary one. Let\u2019s look at how the selectors are stored, be it during a usual recording, or with the <em>Select target<\/em> button.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/GTllUOsWH6i1F90GkBn9_c998DYGJdXYrXIzwPJy-KEXBn3I2bnI5MGC_zZ8lZhqZX-VF9LFikNxLoPI3DS8vp0dkg5gD3TUZ3nsyfmDJTlTrl2rK28wlzLDgvO14SgGlBmhG9KB\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>Here we can see the different locators automatically created for the opencart search bar with the locator method it is using and the possibility to alter it in case we are not comfortable with the automatically generated ones.<\/p>\n\n\n\n<p>With the <em>Select target<\/em> button we can store the locators by selecting the elements directly in the website and then see them highlighted with the <em>Find target<\/em> one to check if it can be effectively found.<br><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/AyotQw7kgdm8JzHPS1lmQ6jB4EiyOPnh4AF4BErixSGH8OUPh50SSWN5-GIsCfKFhgKP2ZS1GfcndLNRMAx4Cf-Vq5LvHP9KWbA6SZur5WC4olsv8Gr1Rh549cmJnLRI7h4_eSm4\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/zk63ETipbACBz1LbWCh4IJ2zw0zoUz875-Zd8rHxSsntjSgLa4h5ynlpeZeisNflW9fcG0YTAi_d7JgsiqPUkkGSvMAzdwpzV7T5dRN-zfAiJBRaVB-7U25hvm8gu3gzmyG56Gq8\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/3k3bf6c7SaHQwO2vSBB1VVcZlbcpddCYfVe6njFR5UXvKnZCYLbK63ttTPhREvczVrOEOc5sltncB_uwndRnbDALMT8xqszkM4g16_vqz6-gi5UiDehOc3ujZkd0TZj-0PwWocJE\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/4mMMu-KibrWm3Nf89hlC11DQ6McsONS8rc1IO3HhHXG6qxXXrRgIpOoATsDhe3Nbag-3tsfz4xvI_dSKWrGQZiVh9Cn80_fX7Zy0pb_ALTtP_nBkmCfGLiHCOUHwwK86M5l_HVZe\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>What happens when in the middle of our execution the element cannot be found? This is the behavior:<br><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/R_OKr3BCNdBEOJkXWoq2I4sckU-Mh5ZbufmvC7anf1_tJqmX3n0794Ilb7xuxcVBuNeaw-2N-FRuBFFdZ6IhDMDqgF5PL3mneb3RJnUiqRcqLNnr6Ft_kgiHSVk0drqu2yj9prQp\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>In this case what happened was that the element that that was trying to find is the first product name on the grid, however the original recorded locator had been done using the iMac product name, so the primary locator, as can be seen, was <strong><em>xpath=\/\/a[contains(text(),\u2019iMac\u2019)]. <\/em><\/strong>Thus, it tried to find this element for 30 seconds but when this timeout finished it resorted to a secondary one which was <strong><em>css=.product-layout:nth-child(1) .caption a<\/em><\/strong>. This can be observed in the logs above.<br><\/p>\n\n\n\n<ul><li><strong>Reusable steps<\/strong><\/li><\/ul>\n\n\n\n<p>Selenium IDE allows us to reuse the same structure for different tests, which can be called from different tests then with the <em>run<\/em> command targeting the tests which holds the common steps.<\/p>\n\n\n\n<p>Let\u2019s look at the following example, we\u2019ll try 2 searches in each test from which the first will produce no results, but in the second we\u2019ll select the first product that shows up, and validate that the page title and the product name have the correct content.<\/p>\n\n\n\n<p>So, we have this test called <em>search_template<\/em> in which we open the opencart, we search the values contained in the variables <em>${search_text1}<\/em>&nbsp; and <em>${search_text2}<\/em> respectively, then in the second search the first product displayed is selected.<br><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/qQUiZovTBSaOBqhEpOlszm8FbDJPQyNjjgPg8DEMJvX3FCuoaO_CtgTDWtVNC-15UG2GF6FfDdhXjSxOoHf-BF8N6E_L0n8P3I89g5ME0MO3e7OVxKGPOP2ZDyhpDUxHk9PYIwth\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>So now we\u2019re going to call this script from the <em>Search laptop and mac<\/em> and <em>Search monitor and samsung<\/em> tests. As displayed, first the variables are set, then the script is called, and the validations take place.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/gSHRxp3AsNAsjpNq2VXl4f-_jlljkhvhZO-P0PrLQUQTlxHBfuQTaWedDoEIGHR7xHhcohi97pLLLC4FUNS4C_nIO2IBrtZcfglV2brYrJqgpLHCwNM2MwWbtIwndh8ZwfuYxL69\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2022\/02\/reusable_steps.mp4\"><\/video><\/figure>\n\n\n\n<p>First test<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2022\/02\/search-mac.mp4\"><\/video><\/figure>\n\n\n\n<p>Second test<br><\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2022\/02\/search-samsung.mp4\"><\/video><\/figure>\n\n\n\n<ul><li><strong>Control flows<\/strong><\/li><\/ul>\n\n\n\n<p>We count with certain commands to include as steps to include conditionals, or loops given a certain condition, or maybe just repeat steps a N number of times. We\u2019re going to try some of this controls in the next scenario:&nbsp;<\/p>\n\n\n\n<p>Let\u2019s store the number of list items in the categories bar, in a variable, then if that number is 8 we\u2019ll click the cart button, otherwise the currency will be selected. After that, we\u2019ll type <em>hello<\/em> that number of times using the <em>times<\/em> command, and then using a variable, a loop that repeats while that variable is less or equal to 5. What that loop does is add the iPhone, that appears below, to the cart, pause for 2 seconds and update the variable. Finally we just check that the text in the cart has 5 products added as expected.<\/p>\n\n\n\n<p>Notice how every time a control flow is closed the end command is used.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/XGVnFnP20OwTbpT-Ursj0acRahsJEzHp2ikstEuQujPS3EOkS5UhTldxPiFCvYGk9DFhHI700FG-H7Z7w0KyjSLQgIZiC0eZnBR01QODx-lSzZ1tbef8o8f0l19rvTMbGfFMCnrU\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>Let\u2019s see it in action.<\/p>\n\n\n\n<figure class=\"wp-block-video aligncenter\"><video controls src=\"https:\/\/abstracta.us\/wp-content\/uploads\/2022\/02\/control-flow.mp4\"><\/video><\/figure>\n\n\n\n<p><br><\/p>\n\n\n\n<ul><li><strong>Code Exports<\/strong><\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh6.googleusercontent.com\/EAs9KbmUainwCoDaocfBKw5AFvkt8-EfanTvccAErQ_EA86DzbOtKOZBud0iz5JxA4StpX8_JQUajdu4UVv2zbuOl-iuLg_jerQiwcfWYmMDTdBblK9Gb22Yjh-GWwVAQqRlpg4U\" alt=\"\"\/><\/figure><\/div>\n\n\n\n<p>The plugin offers the chance to export the code to different languages and testing frameworks as it is displayed below.<\/p>\n\n\n\n<p>We\u2019re going to try the Java for JUnit option and compare how faithful the generated files are to the steps defined in the IDE.<\/p>\n\n\n\n<p>So, next thing we do is export our tests, the control flow one plus both search tests, selecting the options to include origin tracing comments and steps description.<br><\/p>\n\n\n\n<p><strong>Control Flow<\/strong><\/p>\n\n\n\n<p>\/\/ Generated by Selenium IDE<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Generated by Selenium IDE\nimport org.junit.Test;\nimport org.junit.Before;\nimport org.junit.After;\nimport static org.junit.Assert.*;\nimport static org.hamcrest.CoreMatchers.is;\nimport static org.hamcrest.core.IsNot.not;\nimport org.openqa.selenium.By;\nimport org.openqa.selenium.WebDriver;\nimport org.openqa.selenium.firefox.FirefoxDriver;\nimport org.openqa.selenium.chrome.ChromeDriver;\nimport org.openqa.selenium.remote.RemoteWebDriver;\nimport org.openqa.selenium.remote.DesiredCapabilities;\nimport org.openqa.selenium.Dimension;\nimport org.openqa.selenium.WebElement;\nimport org.openqa.selenium.interactions.Actions;\nimport org.openqa.selenium.support.ui.ExpectedConditions;\nimport org.openqa.selenium.support.ui.WebDriverWait;\nimport org.openqa.selenium.JavascriptExecutor;\nimport org.openqa.selenium.Alert;\nimport org.openqa.selenium.Keys;\nimport java.util.*;\nimport java.net.MalformedURLException;\nimport java.net.URL;\npublic class ControlflowTest {\n  private WebDriver driver;\n  private Map&lt;String, Object> vars;\n  JavascriptExecutor js;\n  @Before\n  public void setUp() {\n    driver = new ChromeDriver();\n    js = (JavascriptExecutor) driver;\n    vars = new HashMap&lt;String, Object>();\n  }\n  @After\n  public void tearDown() {\n    driver.quit();\n  }\n  @Test\n  public void controlflow() {\n    \/\/ Test name: Control flow\n    \/\/ Step # | name | target | value\n    \/\/ 1 | open | \\ | \n    driver.get(\"http:\/\/opencart.abstracta.us\\\\\");\n    \/\/ 2 | setWindowSize | 1382x744 | \n    driver.manage().window().setSize(new Dimension(1382, 744));\n    \/\/ 3 | waitForElementVisible | linkText=Your Store | 30000\n    {\n      WebDriverWait wait = new WebDriverWait(driver, 30);\n      wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText(\"Your Store\")));\n    }\n    \/\/ 4 | storeXpathCount | xpath=\/\/ul[contains(@class,'navbar')]\/li | myVar\n    vars.put(\"myVar\", driver.findElements(By.xpath(\"\/\/ul[contains(@class,\\'navbar\\')]\/li\")).size());\n    \/\/ 5 | if | ${myVar}==8 | 3000\n    if ((Boolean) js.executeScript(\"return (arguments[0]==8)\", vars.get(\"myVar\"))) {\n      \/\/ 6 | click | css=.btn-inverse | \n      driver.findElement(By.cssSelector(\".btn-inverse\")).click();\n      \/\/ 7 | else |  | \n    } else {\n      \/\/ 8 | click | css=.btn-group > .btn-link | \n      driver.findElement(By.cssSelector(\".btn-group > .btn-link\")).click();\n      \/\/ 9 | end |  | \n    }\n    \/\/ 10 | times | ${myVar} | \n    Integer times = vars.get(\"myVar\").toString();\n    for(int i = 0; i &lt; times; i++) {\n      \/\/ 11 | sendKeys | name=search | hello \n      driver.findElement(By.name(\"search\")).sendKeys(\"hello \");\n      \/\/ 12 | end |  | \n    }\n    \/\/ 13 | store | 1 | i\n    vars.put(\"i\", \"1\");\n    \/\/ 14 | while | ${i} &lt;= 5 | \n    while ((Boolean) js.executeScript(\"return (arguments[0] &lt;= 5)\", vars.get(\"i\"))) {\n      \/\/ 15 | click | css=.product-layout:nth-child(2) button:nth-child(1) | \n      driver.findElement(By.cssSelector(\".product-layout:nth-child(2) button:nth-child(1)\")).click();\n      \/\/ 16 | pause | 2000 | \n      try {\n        Thread.sleep(2000);\n      } catch (InterruptedException e) {\n        e.printStackTrace();\n      }\n      \/\/ 17 | executeScript | return Number (${i}) + 1 | i\n      vars.put(\"i\", js.executeScript(\"return Number (arguments[0]) + 1\", vars.get(\"i\")));\n      \/\/ 18 | end |  | \n    }\n    \/\/ 19 | click | css=.btn-inverse | \n    driver.findElement(By.cssSelector(\".btn-inverse\")).click();\n    \/\/ 20 | assertText | css=.text-right:nth-child(3) | x 5\n    assertThat(driver.findElement(By.cssSelector(\".text-right:nth-child(3)\")).getText(), is(\"x 5\"));\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>Right off the bat, it can be observed that every single step was converted with the commented reference to the step in the IDE.<\/p>\n\n\n\n<p>We can also see a setup and a tear-down method where the Chrome driver gets created and then terminated, a JavaScript executor and a Hashmap to contain variables.<\/p>\n\n\n\n<p>There are minor issues that can be addressed as how the code is conjured up, namely the declaration of the entire selector every time an element is interacted with or the way in which a condition is handled which, as depicted, is a JavaScript expression, as it is evaluated in the plugin, that gets parsed to a Boolean, so it does not actually use the same condition as it would be declared in the target language. Nevertheless, asides from that it is quite useful to be integrated in a framework, with some tweaks in order to make it more organized, maybe adapt it to a particular pattern like page object model.<\/p>\n\n\n\n<p><strong>Search products<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public void searchtemplate() {\n    driver.get(\"http:\/\/opencart.abstracta.us\/\");\n    driver.manage().window().setSize(new Dimension(1382, 744));\n    {\n      WebDriverWait wait = new WebDriverWait(driver, 30);\n      wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText(\"Your Store\")));\n    }\n    driver.findElement(By.name(\"search\")).click();\n    driver.findElement(By.name(\"search\")).sendKeys(vars.get(\"search_text1\").toString());\n    driver.findElement(By.cssSelector(\".btn-default\")).click();\n    driver.findElement(By.name(\"search\")).click();\n    driver.findElement(By.name(\"search\")).sendKeys(vars.get(\"search_text2\").toString());\n    driver.findElement(By.name(\"search\")).sendKeys(Keys.ENTER);\n    driver.findElement(By.cssSelector(\".product-layout:nth-child(1) .caption a\")).click();\n  }\n  @Test\n  public void searchmonitorandsamsung() {\n    \/\/ Test name: Search monitor and samsung\n    \/\/ Step # | name | target | value\n    \/\/ 1 | store | monitor | search_text1\n    vars.put(\"search_text1\", \"monitor\");\n    \/\/ 2 | store | samsung | search_text2\n    vars.put(\"search_text2\", \"samsung\");\n    \/\/ 3 | run | search_template | \n    searchtemplate();\n    \/\/ 4 | assertTitle | Samsung SyncMaster 941BW | \n    assertThat(driver.getTitle(), is(\"Samsung SyncMaster 941BW\"));\n    \/\/ 5 | assertText | css=h1:nth-child(2) | Samsung SyncMaster 941BW\n    assertThat(driver.findElement(By.cssSelector(\"h1:nth-child(2)\")).getText(), is(\"Samsung SyncMaster 941BW\"));\n  }\n\n@Test\n  public void searchlaptopandmac() {\n    \/\/ Test name: Search laptop and mac\n    \/\/ Step # | name | target | value\n    \/\/ 1 | store | laptop | search_text1\n    vars.put(\"search_text1\", \"laptop\");\n    \/\/ 2 | store | mac | search_text2\n    vars.put(\"search_text2\", \"mac\");\n    \/\/ 3 | run | search_template | \n    searchtemplate();\n    \/\/ 4 | assertTitle | iMac | \n    assertThat(driver.getTitle(), is(\"iMac\"));\n    \/\/ 5 | assertText | css=h1:nth-child(2) | iMac\n    assertThat(driver.findElement(By.cssSelector(\"h1:nth-child(2)\")).getText(), is(\"iMac\"));\n  }\n<\/code><\/pre>\n\n\n\n<p>I have omitted the setup and tear-down methods and the dependencies this time, but it can be observed how exporting a test that depends on another script generates the latter as a function to be called from the test itself, settings the variables beforehand and using them in the common method afterwards.<\/p>\n\n\n\n<p>In short, it\u2019s safe to say that the code generated reflects the steps defined quite accurately, except for the few details mentioned before, which should be no problem to rearrange.<br><\/p>\n\n\n\n<p><strong>Summary<\/strong><\/p>\n\n\n\n<p>To sum up, the plugin is quite effective at what it intends to do, tests can be created on the fly through its record &amp; playback feature reordering the steps, adding or deleting others if necessary, reusing behavior for different tests which is greatly useful. The code exporting feature does a proper job, the rest is up to how the tester uses that code in their tests. Something that could be improved, in my opinion, is having a library of easily identified and categorized selectors where they are stored and from where to pick in case new steps are added or the same element is interacted with one more time, though it\u2019s more of a nice to have than anything. What comes across as truly resourceful is the capability to fallback to another locator when the primary is missing, acting as a fail-safe in case something goes missing, albeit in the code export only the primary is shown, so it would be another nice to have being able to export the entire selector list for an element.<\/p>\n\n\n\n<p><strong>Follow us on <\/strong><a href=\"https:\/\/www.linkedin.com\/company\/abstracta\/\"><strong>Linkedin<\/strong><\/a><strong>, <\/strong><a href=\"https:\/\/www.facebook.com\/AbstractaSoftwareTesting\"><strong>Facebook<\/strong><\/a><strong>, <\/strong><a href=\"https:\/\/twitter.com\/AbstractaUS\"><strong>Twitter<\/strong><\/a><strong>, and <\/strong><a href=\"https:\/\/www.instagram.com\/we_are_abstracta\/\"><strong>Instagram<\/strong><\/a><strong> to be part of our <a href=\"http:\/\/abstracta.us\">community!<\/a><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The original Selenium IDE was a well known plugin for Firefox which helped in the tests creation as a record &amp; playback tool, however as it was no longer supported back in 2017 by the then released&nbsp; Firefox version, it unfortunately ceased to exist. In&#8230;<\/p>\n","protected":false},"author":64,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,61],"tags":[456,457,459,458],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.0.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Bonus: Selenium IDE | Abstracta<\/title>\n<meta name=\"description\" content=\"With the new version of the famous frontend automation tool, some novelties have surfaced. Selenium IDE being one of them.\" \/>\n<meta name=\"robots\" content=\"index, follow\" \/>\n<meta name=\"googlebot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta name=\"bingbot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Bonus: Selenium IDE | Abstracta\" \/>\n<meta property=\"og:description\" content=\"With the new version of the famous frontend automation tool, some novelties have surfaced. Selenium IDE being one of them.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog about AI-powered quality engineering for teams building complex software | Abstracta\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/AbstractaQA\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-23T20:06:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-05-05T21:25:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/abstracta.us\/wp-content\/uploads\/2022\/02\/Abstracta-Blog-Portada-BONUS-Selenium-IDE-_Feb-22-1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"338\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@AbstractaUS\" \/>\n<meta name=\"twitter:site\" content=\"@AbstractaUS\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/abstracta.us\/blog\/#website\",\"url\":\"https:\/\/abstracta.us\/blog\/\",\"name\":\"Blog about AI-powered quality engineering for teams building complex software | Abstracta\",\"description\":\"AI-powered quality engineering\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/abstracta.us\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/lh4.googleusercontent.com\/GTllUOsWH6i1F90GkBn9_c998DYGJdXYrXIzwPJy-KEXBn3I2bnI5MGC_zZ8lZhqZX-VF9LFikNxLoPI3DS8vp0dkg5gD3TUZ3nsyfmDJTlTrl2rK28wlzLDgvO14SgGlBmhG9KB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/#webpage\",\"url\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\",\"name\":\"Bonus: Selenium IDE | Abstracta\",\"isPartOf\":{\"@id\":\"https:\/\/abstracta.us\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/#primaryimage\"},\"datePublished\":\"2022-02-23T20:06:28+00:00\",\"dateModified\":\"2025-05-05T21:25:20+00:00\",\"author\":{\"@id\":\"https:\/\/abstracta.us\/blog\/#\/schema\/person\/8a005ff9ebbaf3e86a1131f051c58533\"},\"description\":\"With the new version of the famous frontend automation tool, some novelties have surfaced. Selenium IDE being one of them.\",\"breadcrumb\":{\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/\",\"url\":\"https:\/\/abstracta.us\/blog\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/\",\"url\":\"https:\/\/abstracta.us\/blog\/software-testing\/\",\"name\":\"Software Testing\"}},{\"@type\":\"ListItem\",\"position\":3,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\",\"url\":\"https:\/\/abstracta.us\/blog\/software-testing\/selenium-ide\/\",\"name\":\"Selenium IDE\"}}]},{\"@type\":[\"Person\"],\"@id\":\"https:\/\/abstracta.us\/blog\/#\/schema\/person\/8a005ff9ebbaf3e86a1131f051c58533\",\"name\":\"Axel Arzuaga\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/abstracta.us\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e8fae706eddce52a13f8229b9cd673be?s=96&d=blank&r=g\",\"caption\":\"Axel Arzuaga\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/14788"}],"collection":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/users\/64"}],"replies":[{"embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/comments?post=14788"}],"version-history":[{"count":5,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/14788\/revisions"}],"predecessor-version":[{"id":14800,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/posts\/14788\/revisions\/14800"}],"wp:attachment":[{"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/media?parent=14788"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/categories?post=14788"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/abstracta.us\/blog\/wp-json\/wp\/v2\/tags?post=14788"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}