Automated Testing for a Confluence add-on?

Has anyone tried to automate testing for a Confluence add-on before? Specially E2E automated testing.
I tried with Pupeteer suggested by a peer, but I just can’t find the content of our add-on’s iframe.

I tried with something like this:

//login to confluence first
await page.goto('https://id.atlassian.com/login?continue=https%3A%2F%2Fmyorg.atlassian.net%2Flogin%3FredirectCount%3D1%26dest-url%3D%252Fwiki%252Findex.action%26application%3Dconfluence&application=confluence')
    var userTextBoxId = '#username'
    var passwdTextBoxId = '#password'
    var continueButton = '#login-submit'
    await page.waitForSelector(userTextBoxId)
    await page.type(userTextBoxId, config.confluenceUser); 
    await page.keyboard.press('Enter')

    await page.waitForSelector(passwdTextBoxId)
    await page.waitFor(1000)
    await page.type(passwdTextBoxId, config.confluencePassword); 
    await page.keyboard.press('Enter')

    page.waitForNavigation()


    await page.waitFor(15000)
// wait for Confluence add on to be fully loaded
    let frames = await page.frames()
    console.log('Number of Frames:',frames.length)
    let  mainFrame = frames.find(f => f.url() === 'https://myorg.atlassian.net/wiki/spaces/COMPANY/overview?mode=global')
    frames.map(f => console.log(`Name: ${f.name()} Url: ${f.url()}`))
    let content = await mainFrame.content()

  //  console.log('Mainframe:',content)
    let childFrames = await mainFrame.childFrames()
    console.log('Number of ChildFrames:',childFrames.length)
    console.log('childFrame 0',await childFrames[0].content())

The info Im getting back is the following:

Number of Frames: 2
Name:  Url: https://myorg.atlassian.net/wiki/spaces/COMPANY/overview?mode=global
Name:  Url: about:blank
Number of ChildFrames: 1
childFrame 0 <html><head></head><body></body></html>

However, if I log the mainFrame content, I can actually see the info for our addon. It’s just that I can’t handle it as iframe. Should I actually do some kind of manual parsing and then open a new page to see the addon info?

<script class="ap-iframe-body-script">
  (function(){
    var data = {
    "addon_key":"confluence-myorg",
    "uniqueKey":"confluence-tmyorg__tt-header",
    "key":"tt-header",
     "moduleType":"webPanels",      "moduleLocation":"atl.general",      "title":"TopNavigation",     "cp":"/wiki",
            "general":"",
    "w":"100%",
    "h":"32px",
    "url":"https://myproj-staging.myorg.net/content/topNavigation?xdm_e=https%3A%2F%2Fmyorg.atlassian.net&xdm_c=channel-confluence-myorg__tt-header&cp=%2Fwiki&xdm_deprecated_addon_key_do_not_use=confluence-myorg&lic=none&cv=1.520.0&jwt=MYBIG_JWT_TOKEN",
     "contextJwt": "MY_JWT_TOKEN_AGAIN",    "structuredContext": "{\"confluence\":{\"content\":{\"type\":\"page\",\"version\":\"1\",\"id\":\"xxx\"},\"space\":{\"key\":\"COMPANY\",\"id\":\"xxxx\"}}}",
    "contentClassifier":"",
    "productCtx":"{\"page.id\":\"xxx\",\"space.key\":\"COMPANY\",\"content.id\":\"xx\",\"content.version\":\"1\",\"page.type\":\"page\",\"page.title\":\"Company\",\"space.id\":\"xxx\",\"content.type\":\"page\",\"page.version\":\"1\"}",
    "timeZone":"Europe/Minsk",
    "origin":"https://myproj-staging.myorg.net",
    "hostOrigin":"https://myorg.atlassian.net",
    "apiMigrations": {
        "gdpr": true
    }
};

What would you recommend? Has someone already tried that before? The thing is that we have different iframes, since we are showing displays in different sections of Confluence.

Thanks in advance for your help

Just to comment, our add-on is built over React framework

Hi @edgarpolancogomez,

Sorry for a delayed response, and thank you for your patience. My experience with Puppeteer is limited, but I’ll try to help you as best as I can.

The return value of mainFrame.content() looks like your frames.find(...) call is not actually finding the iframe you are interested in. We would expect the result to look more like <html><head></head><body></body></html> from the childFrames[0].content() call. You may need to change your find() logic to identify frames in some other manner, possibly checking against frame.name().

Also, instead of using page.waitFor(15000), you can try waiting for an element to be visible in the iframe, e.g. mainFrame.waitForSelector("#my-addon-contents", { visible: true }). This would prevent any unexpected network latency from interfering, and we might see non-empty <head> and <body> content.

Your solutions may not be this simple or straightforward, but hopefully this provides a starting point for troubleshooting your issues.

Robin

Thanks for reply @robin1.

Please check the logic and the responses once again :slight_smile:

   let frames = await page.frames()
   console.log('Number of Frames:',frames.length)
   frames.map(f => console.log(`Name: ${f.name()} Url: ${f.url()}`))

Number of Frames: 2
Name: Url: https://myorg.atlassian.net/wiki/spaces/COMPANY/overview?mode=global
Name: Url: about:blank

So, from all of the page, it only recognizes 2 frames and only the first one is valid.

    let  mainFrame = frames.find(f => f.url() === 'https://myorg.atlassian.net/wiki/spaces/COMPANY/overview?mode=global')
    let content = await mainFrame.content()
//console.log('Mainframe:',content)

frames.find is indeed finding the expected frame for me (from the main page). I can confirm that because I can see the content and find my addon content, if I execute the console.log('Mainframe:',content).
The issue Im seeing is that the Atlassian’s iFrames are not being recognized as childFrames under the mainFrame. Since, this part of the code is returning an empty page instead of the actual iframe content (which I can see if I dump the whole mainFrame content).

    let childFrames = await mainFrame.childFrames()
    console.log('Number of ChildFrames:',childFrames.length)
    console.log('childFrame 0',await childFrames[0].content())

Number of ChildFrames: 1
childFrame 0 <html><head></head><body></body></html>

Does it make sense?

Hi @edgarpolancogomez,

Do you see the iframe loading properly when you run Puppeteer in non-headless mode? If so, Puppeteer should be able to access the iframe. Some more suggestions would be:

  1. You might be getting the page’s child frames too early. You would have to wait for the iframe to be attached
  2. You may need to wait for the content inside the iframe to load as well
  3. You could also try finding the frames based on the content, e.g. (await frame.content()).includes("<some_content_inside_your_iframe>"). Unfortunately it does not look like our Connect addons’ name/url are always available to Puppeteer.

If the iframe is working as expected in non-headless mode, I’m afraid the issue would lie more on Puppeteer’s side than on Confluence. In this case, I think they might provide better guidance than I am able to, unfortunately.

Robin

I had similar problem with webdriverio and as robin1 suggests the fix was to increase the wait time for the iframe.