{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/protractor-visible-text-catch","result":{"data":{"markdownRemark":{"html":"<p>I started exploring <a href=\"www.protractortest.org/#/\">Protractor</a> for front-end / end-to-end testing on an existing project. Protractor is very easy to get started with and allows for rapid development of useful tests.</p>\n<p>However, some behaviour details should be better highlighted in Protractor's documentation. Case in point: <strong>visible text</strong>.</p>\n<p>Let's assume that we have a  page menu implemented with unordered list (UL) + list items (LI) that expands on mouse hover to show child navigation items (which, again, are UL > LIs), which in markup looks like the following:<br /></p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-html line-numbers\"><code class=\"language-html\"><span class=\"token comment\">&lt;!-- menu structure, bootstrap style --></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ul</span><span class=\"token punctuation\">></span></span>\n   <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>...menu-item-1-url<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>menu 1<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span>\n   <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token comment\">&lt;!-- menu item 2 --></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token comment\">&lt;!-- ... child menus --></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ul</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>...child-1<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>menu-item-2<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>child menu 1<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token comment\">&lt;!-- ... more child menus --></span>\n   <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ul</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ul</span><span class=\"token punctuation\">></span></span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n</div>\n</div>\n<br />\nNormally, finding an element in Protractor is quite easy. Here is how we could go about getting the UL &gt; LI.menu-item items that represent our main menu links based on earlier markup:<br />\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\"><span class=\"token function\">element</span><span class=\"token punctuation\">(</span>by<span class=\"token punctuation\">.</span><span class=\"token function\">css</span><span class=\"token punctuation\">(</span><span class=\"token string\">'#main-menu'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">all</span><span class=\"token punctuation\">(</span>by<span class=\"token punctuation\">.</span><span class=\"token function\">css</span><span class=\"token punctuation\">(</span><span class=\"token string\">'.menu-item'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span></span></pre></div>\n<p>The child menu items are collapsed on page load and can't be seen. We have to mouse-over to get the main menu item to expand and show the child items. This is where the visible text \"issue\" kicks in: <strong>Protractor will return a blank string when we try to get the text of the child menu item</strong> - there's nothing for it as far as visible text goes - the user of the page doesn't see any text unless you hover the mouse and get the menu to expand and actually show (I imagine that getting the test to hover over and than test for text should yield the text of the link, but I have not gotten that far).</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\"> <span class=\"token comment\">// initialize to a reference to the submenus of the above DOM menu structure</span>\n<span class=\"token keyword\">var</span> submenus <span class=\"token operator\">=</span>  cy<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'#main-menu ul li a'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// ...</span>\n\n<span class=\"token comment\">// *** NOTE ***</span>\n<span class=\"token comment\">// It turns out that due to CSS forcing these submenu items to be INVISIBLE we can't </span>\n<span class=\"token comment\">// verify the visible text (as below two lines do not validate successfully)</span>\n<span class=\"token comment\">//</span>\n<span class=\"token comment\">// ** this FAILS please note **</span>\n<span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>submenus<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getText</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"child menu 1\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> </code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></pre></div>\n<p>However, we <strong>can</strong> inspect HTML attributes for a given DOM element, regardless of whether they are visible or not:</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre style=\"counter-reset: linenumber NaN\" class=\"language-javascript line-numbers\"><code class=\"language-javascript\"><span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>submenus<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'class'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"menu-item-2 ng-star-inserted\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// and since text is now invisible due to CSS, we can at least use the innerText attribute to get to it and validate</span>\n<span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>submenus<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">getAttribute</span><span class=\"token punctuation\">(</span><span class=\"token string\">'innerText'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"child menu 1\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        </code><span aria-hidden=\"true\" class=\"line-numbers-rows\" style=\"white-space: normal; width: auto; left: 0;\"><span></span><span></span><span></span><span></span></span></pre></div>\n<p>So remember to differentiate between whether the DOM element is visible or not in a given test scenario. If not, use the <code class=\"language-text\">.innerText</code> property to validate the contents of it instead of using <code class=\"language-text\">.getText()</code> method as the latter would return an empty string for DOM elements that are made hidden by CSS.</p>","excerpt":"I started exploring Protractor for front-end / end-to-end testing on an existing project. Protractor is very easy to get started with and allows for rapid…","frontmatter":{"date":"01 December, 2019","path":"/blog/protractor-visible-text-catch","title":"How to verify visible text vs. hidden page elements in Protractor tests"},"fields":{"readingTime":{"text":"3 min read"}}}},"pageContext":{}}}