Test execution inside Backgroundworker apruptly ends on elements with many childelements
Asked Answered
M

2

18

my general setup: we've written a little excel importer with a small gui, that allows non programmers to write and execute gui-tests with commands like "Button.Click". The underlying framework is TestStack.White. After importing the excel file and some other user-intercations the test starts inside a System.ComponentModel.BackgroundWorker, which works fine, as long as i do not look (or even interact with) elements that contain a huge number of childelements.

But as soon as i interact with an TestStack.White.UIItems.WindowItems.Window or an TestStack.White.UIItems.UIItemContainer that has a lot of elements the testexecution just ends.

With interact i mean everything from simple stuff like a not null check or an assignment into a local variable or stuff like asking for it's childcount. Some examples that end the testexecution: 1)

if(theElement != null){ //everything after this line does not happen. The operator doesn't seem to be overloaded
   doStuff(); //it never reaches this point
}

2)

UIItemContainer pointOfInterest = theElement; //everything after this line does not happen

3)

System.Diagnostics.Debug.WriteLine("AmountOfElements: " + UIAnchor.Items.Count); //the output doesn't come. everything after this line does not happen

In windows without hundreds of elements, all three examples work as intended.

By a lot of elements i mean e.g. a Window that has a ScrollView inside, which has a table with dozens or even hundreds of entries, where every entry consists of 3-4 columns with text or a checkbox or something like that.

The Backgroundworkers RunWorkerCompleted and also the Disposed doesn't get called. I get no Exception at all, even with purposely placed try/catch blocks i get nothing out of it. The debugger reaches the line that causes the problem and that's it. Nothing comes afterwards, even with 1h of waiting.

Instead i get just a couple of different "The thread {some hex id} has exited with code 259 (0x103)." in the output window of Visual Studio. This is from my last test execution:

The thread 0x830 has exited with code 259 (0x103).
The thread 0xfc0 has exited with code 259 (0x103).
The thread 0xc04 has exited with code 259 (0x103).

As far as i've understood this message, it means that the Thread is still alive. https://mcmap.net/q/326790/-why-am-i-seeing-multiple-quot-the-thread-0x22c8-has-exited-with-code-259-0x103-quot-messages

If i go into the debuger to check the content of the element that causes the error, i get timeouts on all elements which came after the Items (the List with the childelements), including the Items.

Also the issue is not (or shouldn't be?) that the main thread ends, as it was the case in this thread: Trying to step through BackgroundWorker code in debug but program ends unexpectedly because the gui is still running fine.

Does anyone have an idea what might be happening here or how to fix this issue?

This is how i start the app:

Application app = TestStack.White.Application.Launch(pathToExeFile);
context.setApp(app); //context is a class with static variables to eas the access to all kind of stuff, so that i access it without having 20 parameters in every method (e.g. Button.Click())

Afterwards the user sets which window he wants to test (which might or might not be a modal window - but in windows without hundreds of elements it works):

foreach (Window win in context.getApp().GetWindows()) {
      System.Diagnostics.Debug.WriteLine("###SelectWindow: " + win.Name + " # " + win.PrimaryIdentification + " # " + win.Title);

      if (win.Name.Equals(nameOfWindowToTest)) {
        System.Diagnostics.Debug.WriteLine("###SelectWindow: gefunden");
        context.UIAnchor = win;
        System.Diagnostics.Debug.WriteLine("####SelectWindow: Anz Items: " + context.UIAnchor.Items.Count); //this gets called, but is the very last thing the thread does
        return null; //does not happen
      }
    }

context.UIAnchor is theElement mentioned above. Afterwards the methods set by the user (e.g. Button.Click) gets called. Funnily the context.UIAnchor = win and the output of the items.count works.

Update: If i close the app that is to be tested, before i close the testing programm, i get a ElementNotAvaiableException. So the Thread shouldn't be totally dead.

Met answered 22/4, 2015 at 12:43 Comment(5)
If I would have to take a guess UIItemContainer pointOfInterest = theElement; when you reach the line despite theElement (possibly) still being null is of another datatype then UIItemContainer and that causes the problem. Did you try to put an if around that part? if )theElement is UIItemContainer)Frisch
even if it is still null at this point due to reasons, the [not] null check doesn't work either. :'(Met
I recently had an issue where exceptions within BackgroundWorker.DoWork did not show in Visual Studio, the worker just vanished. Did you try to break on thrown exceptions? I found a missing Invoke in my code and it worked after fixing it.Jackal
@Met please add the code which initialize "theElement"/the excel elements. I think your program loads only the items to display. So the interaction with those elements cause your program to load the rest.Rockwood
@OldFox i've added how i set "theElement". The Excel stuff gets loaded before the app gets startet - so there can't be some form of problem like a racing conditionMet
J
5

Following up on my comment above, I think your BackgroundWorker throws an exception that does not show - maybe because of this Bug / Feature.

Running this small snippet shows no unhandled exception until you mark "Thrown" in the debugging / exception dialogue.

Public Class Form1

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        For I As Integer = 0 To 100
            BackgroundWorker1.ReportProgress(I)
            Threading.Thread.Sleep(25)
            If I = 50 Then Throw (New NullReferenceException)
        Next
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ProgressBar1.Value = 0
    End Sub
End Class

(Sorry for VB, should apply to any CLR)

The sample shows (after clicking the button) a ProgessBar that fills up to 50% and then stops, no BackgroundWorker running, no Done event. Stepping into the Throw simply exits the method.

Edit: My first sample missed the RunWorkerCompleted Event, wich now is firing, so this might be completly unrelated to your question, sorry for the noise.

Jackal answered 29/4, 2015 at 11:34 Comment(2)
no problem. Better some noise than nothing :). And even if it is not usefull to me, the next one who has something similiar might find this thread.Met
great link to the epic tome of obscura and windows loreTodd
T
1

What happens if you switch to the legacy exception handling mode in the app.config?

<configuration>
  <runtime>
    <legacyUnhandledExceptionPolicy enabled="1"/>
  </runtime>
</configuration>
Todd answered 1/5, 2015 at 5:35 Comment(1)
sadly this didn't change the behaviour either way. No extra exceptionmessages, outputs in any of the windows of visual studio or whatsoever. :/Met

© 2022 - 2024 — McMap. All rights reserved.