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
✨amp-consent: support external consent flow #15805
Conversation
@@ -76,6 +79,9 @@ describes.realWin('amp-iframe', { | |||
} | |||
}); | |||
setTrackingIframeTimeoutForTesting(20); | |||
setTrackingIframeCountForTesting(0); | |||
sandbox.stub(error, 'reportError'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rsimha I encountered the issue in #15658 as well.
However the test is intentionally trying to test the misconfiguration. I used allowConsoleError
, but that doesn't work because user().assert()
call #reportError()
, and that will rethrow the error again async.
This is my temporarily solution to fix this, stub #reportError()
, I think a more general solution would be to stub #reportError()
for all tests. WDYT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use expectAsyncConsoleError(<message>)
for async errors. Did you try that?
It's explained in the failure message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hesitate to stub out reportError
since several tests actually check if it fires. However, we could make it so that the error is thrown synchronously during tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And finally, if a mocha test does something asynchronous, it is responsible for calling the done()
callback to indicate that the test has completed. Unfortunately, a lot of our tests fail to do so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use expectAsyncConsoleError() for async errors. Did you try that?
I tried that. It didn't work because I didn't call done()
and the test ended earlier.
I think it will work if I call the #done()
callback. But the problem is that I don't know where to call the done()
callback if I can't stub the #reportError()
. Can I do yield expectAsyncConsoleError(message)
.
The test logic is super simple, check if a misconfiguration results in a function not being called eventually. I don't think it makes much sense to have these unit tests figure out the logic behind #assert()
and call #done()
callback to not break tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talked offline. Will leave the stub there until we figure out a nice general solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meanwhile, #16005 should fix the layoutCallback
issues we were discussing here.
a75eb18
to
346cc1f
Compare
@@ -821,7 +861,8 @@ describes.realWin('amp-iframe', { | |||
expect(addEventListener).to.not.be.called; | |||
}); | |||
|
|||
it('should receive "message" events from <iframe>', function*() { | |||
// TODO (@choumx): Unskip the test | |||
it.skip('should receive "message" events from <iframe>', function*() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@choumx I can't fix this test : ( Skip it for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the heads up.
@@ -163,6 +172,11 @@ export class AmpIframe extends AMP.BaseElement { | |||
|
|||
/** @private */ | |||
assertPosition_() { | |||
if (this.consentContainer_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep amp-iframe
empty of any logic related to other elements.
Two suggestions:
1- Is there an issue with using the normal must provide a placeholder
instead of changing the assertPosition
logic? Presence of placeholder
can be enforced by amp-consent
validation rules (e.g. have a rule that amp-iframe child of amp-consent must have a placeholder)
2- Created a generic list of messages to forward
in amp-iframe
. Have amp-iframe
blindly dispatch an event when it receives one of those messages. For now the list would only contain external-consent-flow
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the mandatory placeholder. This is a pop up iframe, it doesn't much sense to require a placeholder for it.
I can blindly dispatch the event, but it still needs to be laid out to do so. I would still need to check position of the iframe, which requires me to check if the iframe is within an <amp-consent>
component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's keep dependencies one-way and only from amp-consent -> amp-iframe. If mandatory placeholder does not make sense, alternatively amp-consent can inject a placeholder ( if non exists ) during its build callback into decesendant amp-iframe.
Apologies for pushing this, intertwined dependencies can really make the code complex and as AMP codebase grows we need to watch out for code complexity as much as possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Talked offline. We need a smarter API to tell <amp-iframe>
whether it is OK to be placed in first viewport. For example, it is sort of a bug for <amp-iframe>
within <amp-lightbox>
. Even though, it requires user interaction to open the lightbox, an <amp-iframe>
within it still requires a placeholder to be laid out.
For this PR. We agreed that we should always require a placeholder for <amp-iframe>
within <amp-consent>
, because these iframes can be prompted without user interaction, and it makes sense to always include a placeholder to prevent blank space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aghassemi dependency removed. <amp-iframe>
will only listen to consent-response
msg, and blindly dispatch event to the window.
Unfortunately I can't have <amp-consent>
directly listen to that postMessage, because it requires <amp-consent>
to know the exact iframe
to listen to. And there's not API method for that.
669e550
to
ee2d97d
Compare
@lannka has an even stronger opinion about the dependency here 😄....
My only concern is that register event listener within individual component is not optional and might be expensive, especially given that amp-consent needs to query all its child iframe elements here to check source. But if everyone is happy with this approach, I am happy to switch : ) |
@lannka @aghassemi |
ee2d97d
to
84c0227
Compare
@zhouyx I assume the iframe would first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, please remove consentId and sentinel in post message
} | ||
|
||
document.querySelector('#a').onclick = function () { | ||
// parent.postMessage("message to be sent", "http://the-website-that-will-receive-the-msg.com") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bad indentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
As discussed offline. It's really difficult to define the most ideal behaviors here. We decided to add minimal support also put minimum restrictions at first stage. Will expand the functionality if advanced features are required later on. |
Support external consent flow using
<amp-iframe>
and send consent response back using postMessages.cc @choumx @rsimha