{"id":3717,"date":"2020-06-01T07:00:00","date_gmt":"2020-06-01T06:00:00","guid":{"rendered":"https:\/\/www.diogonunes.com\/blog\/?p=3717"},"modified":"2020-05-15T14:22:43","modified_gmt":"2020-05-15T13:22:43","slug":"cypress-pageobjects-inheritance-js","status":"publish","type":"post","link":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/","title":{"rendered":"Cypress: PageObjects using inheritance"},"content":{"rendered":"<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?resize=580%2C387&#038;ssl=1\" alt=\"\" width=\"580\" height=\"387\" class=\"aligncenter size-large wp-image-3724\" srcset=\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?resize=1024%2C683&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?resize=400%2C267&amp;ssl=1 400w, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?resize=768%2C512&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?resize=1200%2C800&amp;ssl=1 1200w, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?w=1500&amp;ssl=1 1500w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\" \/><\/p>\n<blockquote>\n<p>Scenario:<\/p>\n<ul>\n<li>Your web site is deployed on several countries. The behaviour of the page you want to test (e.g. sign up) is mostly the same across countries, however some business rules change per country.<\/li>\n<li>You are using the PageObjects pattern to encapsulate the details of each page. You want to avoid duplicated code.<\/li>\n<\/ul>\n<\/blockquote>\n<p><!--more--><\/p>\n<p>Our goal was to create a <code>SignUpTemplatePage.java<\/code> with the page behaviour that was common across all countries. Then one <code>SignUp&lt;Country&gt;Page.java<\/code> per country, with the specifics of each country, while inheriting the common behaviour from the template page.<\/p>\n<p>It wasn&#8217;t straightforward to achieve it with JavaScript and Cypress&#8217; async behaviour. Thanks to the help of a friendly developer, we did it:<\/p>\n<h3>The test<\/h3>\n<pre><code class=\"js\">describe(\"Sign Up page\", () =&gt; {\n  it(\"creates account when fields are valid\", function() {\n    const userDataObject = {\n      email: \"...\",\n      password: \"...\"\n    }\n\n    \/\/ the E2E test doesn't care about implementation details\n    const page = getSignupAgencyUserPage()\n    page.visit()                        \/\/ env var will determine which country to test\n    page.fillForm(userDataObject)       \/\/ this is different per country\n    page.submitForm()                   \/\/ this is common\n    page.shouldDisplayAccountCreated()  \/\/ this is common\n  })\n})\n<\/code><\/pre>\n<h3>The switch (returns the country PageObject)<\/h3>\n<pre><code class=\"js\">import { ConfigHelper } from \"..\/utils\/configHelper\"\nimport { signupUserPageDE } from \".\/uk\/SignupUserPageDE\"\nimport { signupUserPageFR } from \".\/uk\/SignupUserPageFR\"\nimport { signupUserPagePT } from \".\/pt\/SignupUserPagePT\"\nimport { signupUserPageUK } from \".\/uk\/SignupUserPageUK\"\n\nconst implementations = {\n  de: signupUserPageDE,\n  fr: signupUserPageFR,\n  pt: signupUserPagePT,\n  uk: signupUserPageUK\n}\n\nexport function getSignupUserPage() {\n  const countryCode = ConfigHelper.getCountryCode() \/\/ reads an env var\n  const page = implementations[countryCode]\n  if (!page)\n    throw new Error(`There's no PageObject implementation for the current site: ${countryCode}`)\n  return page\n}\n<\/code><\/pre>\n<h3>The template (contains what is common)<\/h3>\n<pre><code class=\"js\">import { ConfigHelper } from \"..\/utils\/configHelper\";\n\n\/\/ Selectors\nconst btnSubmit = \"#registerSubmit\";\n\nexport class SignupUserPageTemplate {\n  constructor() {\n    \/\/ even though we will never instantiate this class\n  }\n\n  \/\/ Actions\n  visit() {\n    cy.visit(routes.account.signUp);\n  }\n\n  submitForm() {\n    cy.get(btnSubmit).click();\n  }\n\n  \/\/ Assertions\n  shouldDisplayAccountCreated() {\n    cy.url().should(\"include\", routes.account.signUpSuccess);\n  }\n}\n\nexport const signupAgencyUserPageTemplate = new SignupAgencyUserPageTemplate();\n<\/code><\/pre>\n<h3>The country page (contains what is different)<\/h3>\n<pre><code class=\"js\">import { SignupUserPageTemplate } from \"..\/SignupUserPageTemplate\";\n\n\/\/ Selectors\nconst errorInputMessage = \"p .errorbox\";\nconst fieldEmail = `input[name=\"register[email]\"]`;\nconst fieldPhone = `input[name=\"register[default_phone]\"]`;\n\nexport class SignupUserPagePT extends SignupUserPageTemplate {\n  constructor() {\n    super();\n  }\n\n  \/\/ Actions\n  fillForm(account) {\n    cy.get(fieldEmail).type(account.email);\n    cy.get(fieldPhone).type(account.phone);\n  }\n\n  \/\/ Assertions\n  shouldDisplayRequiredFieldsMessage() {\n    const requiredFieldsLength = 2;\n    cy.get(errorInputMessage).should(\"have.length\", requiredFieldsLength);\n  }\n}\n\nexport const signupUserPagePT = new SignupUserPagePT();\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Scenario: Your web site is deployed on several countries. The behaviour of the page you want to test (e.g. sign up) is mostly the same across countries, however some business rules change per country. You are using the PageObjects pattern to encapsulate the details of each page. You want to avoid duplicated code.<\/p>\n","protected":false},"author":1,"featured_media":3724,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[2],"tags":[74,55,31],"class_list":["post-3717","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech","tag-cypress","tag-testing","tag-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Cypress: PageObjects using inheritance - The Geeky Gecko<\/title>\n<meta name=\"description\" content=\"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Cypress: PageObjects using inheritance - The Geeky Gecko\" \/>\n<meta property=\"og:description\" content=\"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\" \/>\n<meta property=\"og:site_name\" content=\"The Geeky Gecko\" \/>\n<meta property=\"article:published_time\" content=\"2020-06-01T06:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Diogo Nunes\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@dialexnunes\" \/>\n<meta name=\"twitter:site\" content=\"@dialexnunes\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Diogo Nunes\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\"},\"author\":{\"name\":\"Diogo Nunes\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c\"},\"headline\":\"Cypress: PageObjects using inheritance\",\"datePublished\":\"2020-06-01T06:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\"},\"wordCount\":138,\"publisher\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c\"},\"image\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1\",\"keywords\":[\"cypress\",\"testing\",\"tutorial\"],\"articleSection\":[\"Technology\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\",\"url\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\",\"name\":\"Cypress: PageObjects using inheritance - The Geeky Gecko\",\"isPartOf\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1\",\"datePublished\":\"2020-06-01T06:00:00+00:00\",\"description\":\"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1\",\"width\":1500,\"height\":1000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.diogonunes.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Cypress: PageObjects using inheritance\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#website\",\"url\":\"https:\/\/www.diogonunes.com\/blog\/\",\"name\":\"The Geeky Gecko\",\"description\":\"The Geeky Gecko\",\"publisher\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.diogonunes.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c\",\"name\":\"Diogo Nunes\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2026\/04\/Geeky-Gecko-2026-v2.png?fit=799%2C799&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2026\/04\/Geeky-Gecko-2026-v2.png?fit=799%2C799&ssl=1\",\"width\":799,\"height\":799,\"caption\":\"Diogo Nunes\"},\"logo\":{\"@id\":\"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/image\/\"},\"sameAs\":[\"http:\/\/www.diogonunes.com\",\"https:\/\/x.com\/dialexnunes\"],\"url\":\"https:\/\/www.diogonunes.com\/blog\/author\/diogo-nunes\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Cypress: PageObjects using inheritance - The Geeky Gecko","description":"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/","og_locale":"en_US","og_type":"article","og_title":"Cypress: PageObjects using inheritance - The Geeky Gecko","og_description":"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.","og_url":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/","og_site_name":"The Geeky Gecko","article_published_time":"2020-06-01T06:00:00+00:00","og_image":[{"width":1500,"height":1000,"url":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","type":"image\/jpeg"}],"author":"Diogo Nunes","twitter_card":"summary_large_image","twitter_creator":"@dialexnunes","twitter_site":"@dialexnunes","twitter_misc":{"Written by":"Diogo Nunes","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#article","isPartOf":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/"},"author":{"name":"Diogo Nunes","@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c"},"headline":"Cypress: PageObjects using inheritance","datePublished":"2020-06-01T06:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/"},"wordCount":138,"publisher":{"@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c"},"image":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","keywords":["cypress","testing","tutorial"],"articleSection":["Technology"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/","url":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/","name":"Cypress: PageObjects using inheritance - The Geeky Gecko","isPartOf":{"@id":"https:\/\/www.diogonunes.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage"},"image":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","datePublished":"2020-06-01T06:00:00+00:00","description":"Maybe your page under test that behaves differently based on a config. You can use JS inheritance to avoid duplicated code on PageObjects with Cypress.","breadcrumb":{"@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#primaryimage","url":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","width":1500,"height":1000},{"@type":"BreadcrumbList","@id":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-inheritance-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.diogonunes.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Cypress: PageObjects using inheritance"}]},{"@type":"WebSite","@id":"https:\/\/www.diogonunes.com\/blog\/#website","url":"https:\/\/www.diogonunes.com\/blog\/","name":"The Geeky Gecko","description":"The Geeky Gecko","publisher":{"@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.diogonunes.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/a6fa79b293f22912664654fcfbd2da0c","name":"Diogo Nunes","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2026\/04\/Geeky-Gecko-2026-v2.png?fit=799%2C799&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2026\/04\/Geeky-Gecko-2026-v2.png?fit=799%2C799&ssl=1","width":799,"height":799,"caption":"Diogo Nunes"},"logo":{"@id":"https:\/\/www.diogonunes.com\/blog\/#\/schema\/person\/image\/"},"sameAs":["http:\/\/www.diogonunes.com","https:\/\/x.com\/dialexnunes"],"url":"https:\/\/www.diogonunes.com\/blog\/author\/diogo-nunes\/"}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/68747470733a2f2f65726c616e67656e776c6164696d69722e66696c65732e776f726470726573732e636f6d2f323031352f30352f6d6174726a6f7363686b612d332e6a7067.jpeg?fit=1500%2C1000&ssl=1","jetpack-related-posts":[{"id":3702,"url":"https:\/\/www.diogonunes.com\/blog\/how-to-build-docker-image-cypress-tests\/","url_meta":{"origin":3717,"position":0},"title":"How to build a Docker image ready to run Cypress tests","author":"Diogo Nunes","date":"11 May, 2020","format":false,"excerpt":"My team decided to build a Docker image that contained Cypress, dependencies and all our end-to-end (E2E) tests. That way, anyone could simply pull the image and with a single command it was ready to run tests. Also, the developers and the CI pipeline we both using the same image,\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/cypress-on-docker.png?fit=1200%2C488&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/cypress-on-docker.png?fit=1200%2C488&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/cypress-on-docker.png?fit=1200%2C488&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/cypress-on-docker.png?fit=1200%2C488&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/cypress-on-docker.png?fit=1200%2C488&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3709,"url":"https:\/\/www.diogonunes.com\/blog\/cypress-automation-template\/","url_meta":{"origin":3717,"position":1},"title":"Cypress Sapling (automation template)","author":"Diogo Nunes","date":"18 May, 2020","format":false,"excerpt":"No need to start with the seed \u2013 plant the sapling! Get it? Because \"Cypress\" is a tree... \ud83e\udd13 On my last project we chose Cypress to automate our E2E tests. During a year and a half we constantly tweaked and improved our test repository. We added more functionary on\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/tzingtao-chow-J8oxnYHBpWM-unsplash-scaled.jpg?fit=960%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/tzingtao-chow-J8oxnYHBpWM-unsplash-scaled.jpg?fit=960%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/tzingtao-chow-J8oxnYHBpWM-unsplash-scaled.jpg?fit=960%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/tzingtao-chow-J8oxnYHBpWM-unsplash-scaled.jpg?fit=960%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":3978,"url":"https:\/\/www.diogonunes.com\/blog\/framework-review-cypress\/","url_meta":{"origin":3717,"position":2},"title":"Framework review: Cypress","author":"Diogo Nunes","date":"4 January, 2021","format":false,"excerpt":"Fast and reliable testing for anything that runs in a browser. It uses Javascript to make setting up, writing, running and debugging tests easy \u2014 for QAs and developers. \u2014 Official website Code Example of automation at GitHub. Use cases \ud83e\udd47 Automate end-to-end (E2E) tests using the UI or the\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/09\/herbert-goetsch-vImJ5GYMMqQ-unsplash-1.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/09\/herbert-goetsch-vImJ5GYMMqQ-unsplash-1.jpg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/09\/herbert-goetsch-vImJ5GYMMqQ-unsplash-1.jpg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/09\/herbert-goetsch-vImJ5GYMMqQ-unsplash-1.jpg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/09\/herbert-goetsch-vImJ5GYMMqQ-unsplash-1.jpg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3685,"url":"https:\/\/www.diogonunes.com\/blog\/asserting-text-using-cypress\/","url_meta":{"origin":3717,"position":3},"title":"Asserting text using Cypress","author":"Diogo Nunes","date":"6 July, 2020","format":false,"excerpt":"If you're using Cypress, eventually you will have to assert some text. However, they provide at least three methods to do that, and from the documentation is not clear the difference between: .should(\"have.text\", \"expected text goes here\") .should(\"include.text\", \"expected text goes here\") .should(\"contain.text\", \"expected text goes here\") Do they all\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"Photo by Sunyu on Unsplash","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/sunyu-jtjS4F8Q7sY-unsplash-scaled.jpg?fit=1200%2C798&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/sunyu-jtjS4F8Q7sY-unsplash-scaled.jpg?fit=1200%2C798&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/sunyu-jtjS4F8Q7sY-unsplash-scaled.jpg?fit=1200%2C798&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/sunyu-jtjS4F8Q7sY-unsplash-scaled.jpg?fit=1200%2C798&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/04\/sunyu-jtjS4F8Q7sY-unsplash-scaled.jpg?fit=1200%2C798&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3942,"url":"https:\/\/www.diogonunes.com\/blog\/cypress-tips-tricks\/","url_meta":{"origin":3717,"position":4},"title":"Tips &#038; Tricks for Cypress","author":"Diogo Nunes","date":"18 January, 2021","format":false,"excerpt":"\ud83c\udfc6 This post was featured in Software Testing Weekly, issue 55 This is a collection of simple and recurring scenarios when writing Cypress tests. For more complex recipes, check the official doc. Setup Abort cypress after first failed test Read a test file from fixtures Assertions Assert the text of\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/08\/hunter-haley-s8OO2-t-HmQ-unsplash-scaled.jpg?fit=1200%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/08\/hunter-haley-s8OO2-t-HmQ-unsplash-scaled.jpg?fit=1200%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/08\/hunter-haley-s8OO2-t-HmQ-unsplash-scaled.jpg?fit=1200%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/08\/hunter-haley-s8OO2-t-HmQ-unsplash-scaled.jpg?fit=1200%2C800&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/08\/hunter-haley-s8OO2-t-HmQ-unsplash-scaled.jpg?fit=1200%2C800&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3590,"url":"https:\/\/www.diogonunes.com\/blog\/cypress-pageobjects-vs-appactions\/","url_meta":{"origin":3717,"position":5},"title":"Cypress: PageObjects vs AppActions","author":"Diogo Nunes","date":"2 March, 2020","format":false,"excerpt":"I use Selenium to write most of my automated checks, and the PageObjects pattern is a must. My current team is using Cypress and, to my surprise, this test framework recommends AppActions instead of PageObjects. So I decided to benchmark both patterns using the following criteria: Can it abstract page\u2026","rel":"","context":"In &quot;Technology&quot;","block_context":{"text":"Technology","link":"https:\/\/www.diogonunes.com\/blog\/category\/tech\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/02\/jason-dent-JVD3XPqjLaQ-unsplash.jpg?fit=1141%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/02\/jason-dent-JVD3XPqjLaQ-unsplash.jpg?fit=1141%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/02\/jason-dent-JVD3XPqjLaQ-unsplash.jpg?fit=1141%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/02\/jason-dent-JVD3XPqjLaQ-unsplash.jpg?fit=1141%2C1200&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/www.diogonunes.com\/blog\/wp-content\/uploads\/2020\/02\/jason-dent-JVD3XPqjLaQ-unsplash.jpg?fit=1141%2C1200&ssl=1&resize=1050%2C600 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/posts\/3717","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/comments?post=3717"}],"version-history":[{"count":3,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/posts\/3717\/revisions"}],"predecessor-version":[{"id":3728,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/posts\/3717\/revisions\/3728"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/media\/3724"}],"wp:attachment":[{"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/media?parent=3717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/categories?post=3717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.diogonunes.com\/blog\/wp-json\/wp\/v2\/tags?post=3717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}