NAR

NAR

Find element in dynamically loaded HTML content with Wallaby

Hello!

I’m new to JavaScript, so I might use wrong terminology, please bear with me :slight_smile: I need to test a page that’s heavy on JavaScript. On loading the page the browser executes a JavaScript function that eventually loads a new form into the page using Ajax. Then I need to click on a button in the freshly loaded HTML code. I can run this in Chrome, I see that the loaded HTML is rendered and the button I need to click is rendered like this:

<div _ngcontent-c2="" class="checkout-header">
      <!---->
      <h1 _ngcontent-c2="" class="heading">
        Foo bar baz
      </h1>
      <i _ngcontent-c2="" alt="X" class="close-button psi psi-times-v1 psi-hover"></i>
    </div>

I have no control over this particular HTML code. I don’t quite understand why the <i> element is used, but the Developer tools in Chrome shows this is the element I need to click on. However, when I try to find this element using Wallaby, I can’t find it. This is the code I’m trying to use:

    selector = "div.checkout-header > i"
    button = Query.css(selector)

but the result is this

  conditions: [at: :all, selected: :any, count: 1, text: nil, visible: true],
  html_validation: nil,
  method: :css,
  result: [],
  selector: "div.checkout-header > i"
}

I see in the screenshot that the downloaded HTML is rendered. What am I doing wrong? I also tried waiting:

   selector = "div.checkout-header > i"
   session
   |> assert_has(Query.css(selector))

but that failed too:

     ** (Wallaby.ExpectationNotMetError) Expected to find 1, visible element that matched the css 'div.checkout-header > i' but 0, visible elements were found.

Marked As Solved

NAR

NAR

Hello!

Thanks for the answers. It turned out the problem was that the new HTML was loaded in an iframe, so I needed to move the focus there using focus_frame. My test still fails occasionally, that :max_wait_time option should help with that.

Also Liked

rsalgado

rsalgado

I don’t know if you figured it out, but as no one else has answered, I might take a stab at this.
I work on QA automation and, even though I haven’t used Elixir for that (thus have not used Wallaby) and have not worked on UI testing recently, maybe my prior experience with it might help here.

It seems that your code is not finding the element. If the selector is correct, then the issue is probably of timing. That happens a lot in UI tests when there’s content rendered dynamically (through JS) and it still isn’t loaded when you query it. My advice would be to:

  1. Check in the developer tools console if that selector is valid. Hint: you can use $$("<your CSS selector>") for CSS selectors and $x("<your XPath selector>") for XPath.
  2. Check in Wallaby’s documentation for some sort of way to wait until an element is found or a timeout limit is reached. After quickly glancing the docs, Browser.find or Browser.retry, but I’m just guessing here.

So far, that’s the most I can say with the current information I have on Wallaby and your problem.
Also, if you have the chance, see if you can use IEX.pry to put a sort of “breakpoint” and do some trial-and-error without having to reload the browser and start from scratch every time.

As for the <i> element, some icon libraries (like FontAwesome) use those elements to put icons, usually with specific classes; not sure if that’s the case here.

michallepicki

michallepicki

I think I can help with that: Wallaby is supposed to wait for the element to appear on the page. The execute_query function contains a Browser.retry call already: wallaby/lib/wallaby/browser.ex at main · elixir-wallaby/wallaby · GitHub and will try again until all validations pass (including number of elements we want to see) or until its timeout (3s by default but you can configure it: wallaby/lib/wallaby/browser.ex at main · elixir-wallaby/wallaby · GitHub ).

@NAR You can try increasing the :max_wait_time config value. (I think it would be cool to be able to tune it per query execution, we could look into adding support for that to Wallaby). Another thing you could do is have a custom helper for waiting that takes the timeout as an argument. You could use Browser.execute_query or Browser.has and/or Browser.retry as its building blocks (or copy&paste&modify them to hack something together :wink: ). You could make a few versions of it, i.e. one that ignores query result and returns the parent, one that takes a function block to execute on the found element, and one that would return the found element. I’m curious what you end up with so please do share your findings or problems you stumble upon.

Where Next?

Popular in Questions Top

jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Other popular topics Top

Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement