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

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
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
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
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
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
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
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement