Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Incomplete jasmine stack-trace in case of utam method caused a test failure #122

Open
2 tasks
tanujvishnoi opened this issue Feb 6, 2023 · 13 comments
Open
2 tasks
Labels
bug Something isn't working P3 Minor impaired functionality that may be addressed in the next release

Comments

@tanujvishnoi
Copy link

tanujvishnoi commented Feb 6, 2023

Actual behavior

Hey everyone, we're working with utam-webdriver-jasmine flavors along with TS and during spec run we have noticed the stack trace get truncated if a test failed because of web-element issue [utam waitfor- method or element is not in scope],
in-short we got a complete stack trace in case of assertion failure like which spec line and file, but other failures wont populate complete stack-traces & the error source,

  • Unable to compile a Page Object
  • Invalid generated code
  • Runtime error

What is your expected behavior?

during any failure, the complete stack-trace should be visible indicating the spec line which actually caused this issue

Steps to reproduce

1: Create a TS-Jasmine-utam-wdio based project
2: Create few utam files with wait for methods that will fail or some non-existing locators
3: Draft spec file and use utam file and called specific methods or access locators stated in step2
4: Run the spec and observe the stack traces

Environment

  • Node.js: v16.18.1
  • OS: Windows
  • Browser: Chrome
  • Browser Version: Latest
  • Type script
    • typescript: "^4.8.3",
  • Jasmine
    • @wdio/jasmine-framework: "^7.24.1",

Additional context

Refer to attached truncated stack-traces
1:
locator_

2:

waitfor

@tanujvishnoi tanujvishnoi added bug Something isn't working needs triaging labels Feb 6, 2023
@olivier-martin-sf
Copy link
Contributor

Hi @tanujvishno, thank you for taking the time to open this issue.

Hey everyone, we're working with utam-webdriver-jasmine flavors along with TS

May you clarify what's utam-webdriver-jasmine? We don't have such package published on npm. Is it a package that you developed internally or is it terminology meaning that you are using WebdriverIO with Jasmine?

in-short we got a complete stack trace in case of assertion failure like which spec line and file, but other failures won't populate complete stack traces & the error source

Would you be able to set up a minimal repository where the unwanted behavior can be reproduced? That would be helpful to see a test that exhibits this behavior (it can be against any Web page and doesn't have to be against a Salesforce test environment).

@tanujvishnoi
Copy link
Author

sorry for the confusion , Yes, by utam-webdriver-jasmine I meant webdriverIO with jasmine , I'll share a repo url soon reproducing this issue

@tanujvishnoi
Copy link
Author

@olivier-martin-sf https://github.com/tanujvishnoi/utam_demo , here is the demo code to produce truncated stack trace

@olivier-martin-sf
Copy link
Contributor

Thank you so much for providing the minimal repository, we are going to look into this as soon as we have the capacity to do so (probably next week)

@olivier-martin-sf
Copy link
Contributor

Hi @tanujvishnoi, I look into this issue and I would like to clarify the problem statement and expectations.

Digging deeper, if I understood the problem statement correctly, it seems that the issue appears in the context of a waitFor predicate.

  • May you confirm that the first use case (Getting non-existing element) works correctly?
  • May you confirm that the second use case (Getting non-existing element inside a predicate) reproduces the original issue?
  • May you define what would be a correct scenario (providing an example of an expected stack trace)?

Getting non-existing element

From my observations, if I am trying to get a non-existing element, the stack trace provides the Jasmine context (with the position of the line that throws the error in the spec file). To reproduce try to define a public element with a CSS selector that doesn't match any element and try to invoke the function that gets the element from the test. For example:

{
  // other non-relevant properties
  "elements": [
    {
      "name": "userNameInput",
      "type": ["editable", "clickable"],
      "public": true,
      "selector": {
        "css": ".dsadsads"
      }
    }
  ],
  // other non-relevant properties
}

And try to invoke this from the test:

await demoPage.getUserNameInput();

This should throw an error with the following stack trace:

[0-0] Error: Can't find elements with locator 'dsadsads' inside its scope element.
[0-0]     at ElementWdioAdapter.findElements (/Users/JaneDoe/utam_demo/node_modules/wdio-utam-service/build/adapters/element-adapter.js:95:19)
[0-0]     at processTicksAndRejections (node:internal/process/task_queues:96:5)
[0-0]     at async ElementWdioAdapter.findElement (/Users/JaneDoe/utam_demo/node_modules/wdio-utam-service/build/adapters/element-adapter.js:88:17)
[0-0]     at async Demo2.getUserNameInput (/Users/JaneDoe/utam_demo/pageObjects/demo2.js:44:23)
[0-0]     at async UserContext.f1 (/Users/JaneDoe/utam_demo/tests/spec/test2.spec.ts:9:7)

As you can see the last line of the stack trace is the Jasmine UserContext.

Note: f1 is the name of the function that wraps the test, I avoid arrow functions in tests to have more explicit context in the stack trace.

Getting non-existing element inside a predicate

However if I am trying to wait for an element that doesn't exist in a waitFor predicate such as:

// other non-relevant properties
"methods:"  [
   {
      "name": "waitForNonExistentElement",
      "compose": [
        {
          "apply": "waitFor",
          "args": [
            {
              "type": "function",
              "predicate": [
                {
                  "element": "root",
                  "apply": "containsElement",
                  "args": [
                    {
                      "type": "locator",
                      "value": {
                        "css": ".fdskjfdkslj"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
]
// other non-relevant properties

And I am trying to invoke this method from my test:

await demoPage.waitForNonExistentElement();

This is the error that I am having:

[0-0] Error: Timeout while waiting for condition after 4639ms.
[0-0]     at handlePollTimeout (/Users/JaneDoe/utam_demo/node_modules/@utam/core/build/helper-methods.js:53:28)
[0-0]     at /Users/JaneDoe/utam_demo/node_modules/@utam/core/build/helper-methods.js:62:25
[0-0]     at processTicksAndRejections (node:internal/process/task_queues:96:5)

There we don't have the information about the test context (we don't know which line in our spec file generated the error).

@tanujvishnoi
Copy link
Author

Hi @olivier-martin-sf

Thanks for sharing the examples . Yes the issue eventually reproducible for predicate . If a condition get failed inside a predicate , we did not get the full error stack
Apart from the above 2 conditions, i added one more where we expect a hidden element to get visible .
https://github.com/tanujvishnoi/utam_demo

`1) reproduce truncate error stack Case 1: Getting no existing element directly using getter
Error: Can't find elements with locator 'dsadsads' inside its scope element.
Error: Can't find elements with locator 'dsadsads' inside its scope element.
at ElementWdioAdapter.findElements (\utam_demo\node_modules\wdio-utam-service\build\adapters\element-adapter.js:95:19)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async ElementWdioAdapter.findElement (\utam_demo\node_modules\wdio-utam-service\build\adapters\element-adapter.js:88:17)
at async Demo.getUserNameInput (\utam_demo\pageObjects\demo.js:50:23)
at async UserContext. (\utam_demo\tests\spec\test.spec.ts:12:21)

  1. reproduce truncate error stack Case 2: Getting no existing element inside a method
    Error: Can't find elements with locator 'dsadsads' inside its scope element.
    Error: Can't find elements with locator 'dsadsads' inside its scope element.
    at ElementWdioAdapter.findElements (\utam_demo\node_modules\wdio-utam-service\build\adapters\element-adapter.js:95:19)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ElementWdioAdapter.findElement (\utam_demo\node_modules\wdio-utam-service\build\adapters\element-adapter.js:88:17)
    at async Demo.getUserNameInput (\utam_demo\pageObjects\demo.js:50:23)
    at async Demo.clickUserName (\utam_demo\pageObjects\demo.js:85:29)
    at async UserContext. (\utam_demo\tests\spec\test.spec.ts:23:9)

  2. reproduce truncate error stack Case 3: Getting no existing inside a predicate
    Error: Timeout while waiting for condition after 10484ms.
    Error: Timeout while waiting for condition after 10484ms.
    at handlePollTimeout (\utam_demo\node_modules@utam\core\build\helper-methods.js:53:28)
    at \utam_demo\node_modules@utam\core\build\helper-methods.js:62:25
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

  3. reproduce truncate error stack Case 4: Wait for visibility of hidden search input
    Error: Timeout while waiting for condition after 10265ms.
    Error: Timeout while waiting for condition after 10265ms.
    at handlePollTimeout (\utam_demo\node_modules@utam\core\build\helper-methods.js:53:28)
    at \utam_demo\node_modules@utam\core\build\helper-methods.js:62:25
    at runMicrotasks ()
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

  4. reproduce truncate error stack Case 5: Get hidden element ,then wait for visibility
    Error: Timeout while waiting for condition after 10212ms.
    Error: Timeout while waiting for condition after 10212ms.
    at handlePollTimeout (\utam_demo\node_modules@utam\core\build\helper-methods.js:53:28)
    at \utam_demo\node_modules@utam\core\build\helper-methods.js:62:25`

@olivier-martin-sf
Copy link
Contributor

Thanks, I will pull your changes.

Judging by your stack traces example, 1 & 2 provide the full stack trace but 3, 4 & 5 don't and all of them are related to timeout errors so can we narrow the problem statement to: "we don't have the full stack trace when there's a wait condition that times out?"

Do you agree with that? If yes, I will start investigating why we shallow the context in waitFor

@tanujvishnoi
Copy link
Author

Yes absolutely agree.

@olivier-martin-sf
Copy link
Contributor

After some investigation, I can confirm that I can reproduce the issue. It happens when the waitFor function is being invoked and the condition doesn't return a truthy value before the timeout.

The problem is due to the execution of an async function that is triggered by a timer as described here: https://github.com/sindresorhus/got/blob/main/documentation/async-stack-traces.md. I created an item in our backlog so that we can fix the issue in a future release.

Thank you for reporting this

@olivier-martin-sf olivier-martin-sf added P3 Minor impaired functionality that may be addressed in the next release and removed needs triaging labels Mar 2, 2023
@tanujvishnoi
Copy link
Author

Hi @olivier-martin-sf just taking a follow up, please let us know once we have a fix for this issue

@irinash13
Copy link

Hello @tanujvishnoi , what company do you represent?

@KierenLWoods
Copy link

@olivier-martin-sf Just wondered if there are any updates on this one and any plans as to when it may be fixed?

@olivier-martin-sf
Copy link
Contributor

Hi @tanujvishnoi & @KierenLWoods, this issue is being tracked in our backlog but hasn't been prioritised yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working P3 Minor impaired functionality that may be addressed in the next release
Projects
None yet
Development

No branches or pull requests

4 participants