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

test(release): Add Python script to test UIs #3232

Merged
merged 13 commits into from
Dec 6, 2023

Conversation

mmicu
Copy link
Contributor

@mmicu mmicu commented Jul 11, 2023

Description

Add a Python script that automate the testing of the Frontend and Candid UIs by using playwright.

How Has This Been Tested?

The script was executed locally. It should produce a similar output.
Moreover, it fails immediately if it does not find the expected fields as well as warnings and errors.

$ python3 scripts/test-uis.py --frontend_url 'http://localhost:4943/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai' --candid_url 'http://localhost:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai' --browsers chromium firefox webkit
2023-07-11 20:49:12,779 - INFO - Testing "Frontend UI" at "http://localhost:4943/?canisterId=bd3sg-teaaa-aaaaa-qaaba-cai"
2023-07-11 20:49:13,128 - INFO - Checking "chromium" browser
2023-07-11 20:49:13,869 - INFO - Setting name "my name"
2023-07-11 20:49:13,936 - INFO - Clicking button "Click Me!"
2023-07-11 20:49:14,093 - INFO - "Hello, my name!" found in "#greeting"
2023-07-11 20:49:14,093 - INFO - Checking console logs
2023-07-11 20:49:14,094 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'ambient-light-sensor'."
2023-07-11 20:49:14,095 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'battery'."
2023-07-11 20:49:14,095 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'document-domain'."
2023-07-11 20:49:14,095 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-not-rendered'."
2023-07-11 20:49:14,096 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-out-of-viewport'."
2023-07-11 20:49:14,096 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'navigation-override'."
2023-07-11 20:49:14,096 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'web-share'."
2023-07-11 20:49:14,097 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'speaker-selection'."
2023-07-11 20:49:14,097 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'conversion-measurement'."
2023-07-11 20:49:14,097 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'focus-without-user-activation'."
2023-07-11 20:49:14,098 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'interest-cohort'."
2023-07-11 20:49:14,098 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'sync-script'."
2023-07-11 20:49:14,098 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'trust-token-redemption'."
2023-07-11 20:49:14,099 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'vertical-scroll'."
2023-07-11 20:49:14,099 - INFO - Console logs are ok
2023-07-11 20:49:14,209 - INFO - Checking "firefox" browser
2023-07-11 20:49:14,861 - INFO - Setting name "my name"
2023-07-11 20:49:14,909 - INFO - Clicking button "Click Me!"
2023-07-11 20:49:15,041 - INFO - "Hello, my name!" found in "#greeting"
2023-07-11 20:49:15,042 - INFO - Checking console logs
2023-07-11 20:49:15,042 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'ambient-light-sensor'."
2023-07-11 20:49:15,042 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'battery'."
2023-07-11 20:49:15,042 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'document-domain'."
2023-07-11 20:49:15,043 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-not-rendered'."
2023-07-11 20:49:15,043 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-out-of-viewport'."
2023-07-11 20:49:15,043 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'navigation-override'."
2023-07-11 20:49:15,043 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'web-share'."
2023-07-11 20:49:15,044 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'speaker-selection'."
2023-07-11 20:49:15,044 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'conversion-measurement'."
2023-07-11 20:49:15,044 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'focus-without-user-activation'."
2023-07-11 20:49:15,044 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'interest-cohort'."
2023-07-11 20:49:15,045 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'sync-script'."
2023-07-11 20:49:15,045 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'trust-token-redemption'."
2023-07-11 20:49:15,045 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'vertical-scroll'."
2023-07-11 20:49:15,045 - INFO - Console logs are ok
2023-07-11 20:49:15,151 - INFO - Checking "webkit" browser
2023-07-11 20:49:15,851 - INFO - Setting name "my name"
2023-07-11 20:49:15,898 - INFO - Clicking button "Click Me!"
2023-07-11 20:49:16,009 - INFO - "Hello, my name!" found in "#greeting"
2023-07-11 20:49:16,009 - INFO - Checking console logs
2023-07-11 20:49:16,010 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'ambient-light-sensor'."
2023-07-11 20:49:16,010 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'battery'."
2023-07-11 20:49:16,010 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'document-domain'."
2023-07-11 20:49:16,010 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-not-rendered'."
2023-07-11 20:49:16,010 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'execution-while-out-of-viewport'."
2023-07-11 20:49:16,011 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'navigation-override'."
2023-07-11 20:49:16,011 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'web-share'."
2023-07-11 20:49:16,011 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'speaker-selection'."
2023-07-11 20:49:16,011 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'conversion-measurement'."
2023-07-11 20:49:16,011 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'focus-without-user-activation'."
2023-07-11 20:49:16,012 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Origin trial controlled feature not enabled: 'interest-cohort'."
2023-07-11 20:49:16,012 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'sync-script'."
2023-07-11 20:49:16,012 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'trust-token-redemption'."
2023-07-11 20:49:16,012 - WARNING - Skipping Permissions-Policy warning. log.text="Error with Permissions-Policy header: Unrecognized feature: 'vertical-scroll'."
2023-07-11 20:49:16,013 - INFO - Console logs are ok
2023-07-11 20:49:16,125 - INFO - Testing "Candid UI" at "http://localhost:4943/?canisterId=be2us-64aaa-aaaaa-qaabq-cai&id=bkyz2-fmaaa-aaaaa-qaaaq-cai"
2023-07-11 20:49:16,651 - INFO - Checking "chromium" browser
2023-07-11 20:49:17,555 - INFO - Setting text to "hello, world"
2023-07-11 20:49:17,817 - INFO - Clicking button "Query"
2023-07-11 20:49:17,883 - INFO - Setting text to ""
2023-07-11 20:49:17,912 - INFO - Clicking button "Random"
2023-07-11 20:49:18,011 - INFO - "› greet("hello, world")" found in #output-list at position 0
2023-07-11 20:49:18,011 - INFO - "("Hello, hello, world!")" found in #output-list at position 1
2023-07-11 20:49:18,011 - INFO - "› greet("ti2xjcu")" found in #output-list at position 2
2023-07-11 20:49:18,011 - INFO - "("Hello, ti2xjcu!")" found in #output-list at position 3
2023-07-11 20:49:18,012 - INFO - #output-list lines are defined correctly
2023-07-11 20:49:18,012 - INFO - Checking console logs
2023-07-11 20:49:18,012 - WARNING - Found warning, but it was expected (log.type="Invalid asm.js: Unexpected token", endpoint="/index.js")
2023-07-11 20:49:18,012 - WARNING - Found error, but it was expected (log.type="Failed to load resource: the server responded with a status of 404 (Not Found)", endpoint="/read_state")
2023-07-11 20:49:18,012 - WARNING - Found warning, but it was expected (log.type="Expected to find result for path [object Object], but instead found nothing.", endpoint="/index.js")
2023-07-11 20:49:18,012 - WARNING - Found warning, but it was expected (log.type="Error: Server returned an error:
  Code: 404 (Not Found)
  Body: Custom section name not found.

    at j.readState (http://localhost:4943/index.js:2:11709)
    at async http://localhost:4943/index.js:2:97683
    at async Promise.all (index 0)
    at async Module.UA (http://localhost:4943/index.js:2:98732)
    at async Object.getNames (http://localhost:4943/index.js:2:266156)
    at async http://localhost:4943/index.js:2:275479", endpoint="/index.js")
2023-07-11 20:49:18,012 - INFO - Console logs are ok
2023-07-11 20:49:18,119 - INFO - Checking "firefox" browser
2023-07-11 20:49:18,980 - INFO - Setting text to "hello, world"
2023-07-11 20:49:19,330 - INFO - Clicking button "Query"
2023-07-11 20:49:19,455 - INFO - Setting text to ""
2023-07-11 20:49:19,511 - INFO - Clicking button "Random"
2023-07-11 20:49:19,637 - INFO - "› greet("hello, world")" found in #output-list at position 0
2023-07-11 20:49:19,637 - INFO - "("Hello, hello, world!")" found in #output-list at position 1
2023-07-11 20:49:19,637 - INFO - "› greet("j7usei")" found in #output-list at position 2
2023-07-11 20:49:19,638 - INFO - "("Hello, j7usei!")" found in #output-list at position 3
2023-07-11 20:49:19,638 - INFO - #output-list lines are defined correctly
2023-07-11 20:49:19,638 - INFO - Checking console logs
2023-07-11 20:49:19,639 - WARNING - Found warning, but it was expected (log.type="Invalid asm.js: Unexpected token", endpoint="/index.js")
2023-07-11 20:49:19,639 - WARNING - Found error, but it was expected (log.type="Failed to load resource: the server responded with a status of 404 (Not Found)", endpoint="/read_state")
2023-07-11 20:49:19,639 - WARNING - Found warning, but it was expected (log.type="Expected to find result for path [object Object], but instead found nothing.", endpoint="/index.js")
2023-07-11 20:49:19,640 - WARNING - Found warning, but it was expected (log.type="Error: Server returned an error:
  Code: 404 (Not Found)
  Body: Custom section name not found.

    at j.readState (http://localhost:4943/index.js:2:11709)
    at async http://localhost:4943/index.js:2:97683
    at async Promise.all (index 0)
    at async Module.UA (http://localhost:4943/index.js:2:98732)
    at async Object.getNames (http://localhost:4943/index.js:2:266156)
    at async http://localhost:4943/index.js:2:275479", endpoint="/index.js")
2023-07-11 20:49:19,640 - INFO - Console logs are ok
2023-07-11 20:49:19,729 - INFO - Checking "webkit" browser
2023-07-11 20:49:20,578 - INFO - Setting text to "hello, world"
2023-07-11 20:49:21,112 - INFO - Clicking button "Query"
2023-07-11 20:49:21,221 - INFO - Setting text to ""
2023-07-11 20:49:21,271 - INFO - Clicking button "Random"
2023-07-11 20:49:21,391 - INFO - "› greet("hello, world")" found in #output-list at position 0
2023-07-11 20:49:21,392 - INFO - "("Hello, hello, world!")" found in #output-list at position 1
2023-07-11 20:49:21,392 - INFO - "› greet("ul67tu")" found in #output-list at position 2
2023-07-11 20:49:21,392 - INFO - "("Hello, ul67tu!")" found in #output-list at position 3
2023-07-11 20:49:21,392 - INFO - #output-list lines are defined correctly
2023-07-11 20:49:21,393 - INFO - Checking console logs
2023-07-11 20:49:21,393 - WARNING - Found warning, but it was expected (log.type="Invalid asm.js: Unexpected token", endpoint="/index.js")
2023-07-11 20:49:21,393 - WARNING - Found error, but it was expected (log.type="Failed to load resource: the server responded with a status of 404 (Not Found)", endpoint="/read_state")
2023-07-11 20:49:21,393 - WARNING - Found warning, but it was expected (log.type="Expected to find result for path [object Object], but instead found nothing.", endpoint="/index.js")
2023-07-11 20:49:21,394 - WARNING - Found warning, but it was expected (log.type="Error: Server returned an error:
  Code: 404 (Not Found)
  Body: Custom section name not found.

    at j.readState (http://localhost:4943/index.js:2:11709)
    at async http://localhost:4943/index.js:2:97683
    at async Promise.all (index 0)
    at async Module.UA (http://localhost:4943/index.js:2:98732)
    at async Object.getNames (http://localhost:4943/index.js:2:266156)
    at async http://localhost:4943/index.js:2:275479", endpoint="/index.js")
2023-07-11 20:49:21,394 - INFO - Console logs are ok
2023-07-11 20:49:21,515 - INFO - DONE!

Checklist:

  • The title of this PR complies with Conventional Commits.
  • I have edited the CHANGELOG accordingly.
  • I have made corresponding changes to the documentation.

Copy link
Member

@ericswanson-dfinity ericswanson-dfinity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

What we're looking for is a mix between this and the now-closed #2519: something we can run as part of a pass/fail e2e test that's run with the rest of our CI checks. We'll leave the manual verification in scripts/release.sh in place while we build confidence in the e2e test.

It's fine if you want to also run the headless browser test in scripts/release.sh, but it should be pass/fail, rather than involving manual inspection of the output of a python script. What we're looking for would be cases where the automated test didn't catch something, but the manual verification did.

@mmicu
Copy link
Contributor Author

mmicu commented Jul 16, 2023

Nice!

What we're looking for is a mix between this and the now-closed #2519: something we can run as part of a pass/fail e2e test that's run with the rest of our CI checks. We'll leave the manual verification in scripts/release.sh in place while we build confidence in the e2e test.

Thanks for the feedback.

So I imagine that I can have something very similar to the closed MR, especially for the YAML configurations, right?
However, I am not sure about the purpose of .github/workflows/e2e-selenium.yml, since the script is also called from here.

It's fine if you want to also run the headless browser test in scripts/release.sh, but it should be pass/fail, rather than involving manual inspection of the output of a python script. What we're looking for would be cases where the automated test didn't catch something, but the manual verification did.

Then maybe it can be added after the manual inspection, just to confirm that new warnings or new errors are not introduced by a new version.

@ericswanson-dfinity
Copy link
Member

However, I am not sure about the purpose of .github/workflows/e2e-selenium.yml, since the script is also called from here.

No need for any equivalent of that e2e-selenium.yml workflow, since we'll be adding one to e2e workflow.

Copy link
Contributor

@smallstepman smallstepman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've let CI run for this PR, and it bugged out in a bit unexpected place: https://github.com/dfinity/sdk/actions/runs/5591534054/jobs/10227915747?pr=3232

Nothing obvious jumps at me why it crashed there, so I've compared .jobs.test.steps and .jobs.ui_test.steps; these were some of the differences I was able to find:

.github/workflows/e2e.yml Outdated Show resolved Hide resolved
.github/workflows/e2e.yml Outdated Show resolved Hide resolved
.github/workflows/e2e.yml Outdated Show resolved Hide resolved
@smallstepman
Copy link
Contributor

smallstepman commented Jul 19, 2023

CI run is in progress https://github.com/dfinity/sdk/actions/runs/5602950032?pr=3232

@smallstepman
Copy link
Contributor

we're almost there :) https://github.com/dfinity/sdk/actions/runs/5602950032/jobs/10249202379

@mmicu
Copy link
Contributor Author

mmicu commented Jul 20, 2023

I found a silly bug in the script. It should solve most of the issues.

However, I cannot make webkit work. Is it needed? Locally, chromium and firefox work fine.

@smallstepman
Copy link
Contributor

smallstepman commented Jul 20, 2023

I'm afraid yes, webkit is Safari so it is a major player in the browser game. What is the error message that you're getting?

Btw, have you maybe looked into how hard it would be to also include tests on mobile (android chrome & ios safari)? Having those is basically an endgame for us

@mmicu
Copy link
Contributor Author

mmicu commented Jul 20, 2023

I'm afraid yes, webkit is Safari so it is a major player in the browser game. What is the error message that you're getting?

In the Frontend UI, the greeting section is empty once the button is clicked, but it is working for the other two browsers.
I have checked several approaches, but I always got an empty string when I try to retrieve it.

Btw, have you maybe looked into how hard it would be to also include tests on mobile (android chrome & ios safari)? Having those is basically an endgame for us

Good point. Nope, I did not check it yet.

@smallstepman
Copy link
Contributor

What OS are you running this on? I'll check tomorrow on macOS

First thing I'd try to do is try to run launch the browser in headed mode, have you maybe tried that already?

@mmicu
Copy link
Contributor Author

mmicu commented Jul 21, 2023

What OS are you running this on? I'll check tomorrow on macOS

Ubuntu 22.04 (WSL).

First thing I'd try to do is try to run launch the browser in headed mode, have you maybe tried that already?

Not yet.

Please, try with the following snippet:

from playwright.sync_api import sync_playwright

with sync_playwright() as playwright:
    # Empty value
    browser = playwright.webkit.launch(headless=True)
    
    # OK
    # browser = playwright.firefox.launch(headless=True)
    
    context = browser.new_context()
    page = browser.new_page()
    frontend_url = '...'
    page.goto(frontend_url)
    
    page.get_by_label('Enter your name:').fill('foo')
    page.get_by_role('button', name='Click Me!').click()

    section_element = page.query_selector('#greeting')
    print(section_element.text_content())

    browser.close()

@mmicu
Copy link
Contributor Author

mmicu commented Jul 22, 2023

That's why it is not working, which cites Safari keeps forcing HTTPS on localhost.

I am still checking how to solve it from Playwright.

EDIT: maybe changing the headers in the response could help. It seems that it is supported from version 1.29. I will test it in the evening and let you know.

@smallstepman
Copy link
Contributor

smallstepman commented Jul 24, 2023

Yes, looks like you're right... I tried to look into how to generate the certificate but didn't found anything so far

Also, when I try to open my locally deployed canister in Safari, the website doesn't load CSS or images. When I try to click on the button, it errors out with Safari can't open the page because can't establish a secure connection - @ericswanson-dfinity could you please check if this is also the case for you?

@mmicu
Copy link
Contributor Author

mmicu commented Jul 27, 2023

I was able to replicate and fix the issues locally.

Not sure if we actually need to parse the warnings and errors, since we still have the manual checks during the release process.

@ericswanson-dfinity
Copy link
Member

@ericswanson-dfinity could you please check if this is also the case for you?

To follow up on this here: this is happening on Safari due to the security policy headers that we introduced in dfx 0.13.1.

Copy link
Contributor

@smallstepman smallstepman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing work! I'm intrigued by the usage of _ before each variable/function name, what's the reasoning behind it?

.github/workflows/e2e.yml Outdated Show resolved Hide resolved
Co-authored-by: Marcin Nowak-Liebiediew <[email protected]>
@mmicu
Copy link
Contributor Author

mmicu commented Dec 5, 2023

Hi @ericswanson-dfinity, could you please review the PR? The script seems to work now.

@smallstepman smallstepman enabled auto-merge (squash) December 6, 2023 00:21
@smallstepman smallstepman merged commit 826cf17 into dfinity:master Dec 6, 2023
172 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants