blob: 594c0f4634f922da9000369ddfc4010536e00364 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/sync/sync_passphrase_dialog.h"
#include <string>
#include <string_view>
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/strings/string_util.h"
#include "base/test/mock_callback.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/base/interaction/polling_state_observer.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "url/gurl.h"
namespace {
DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(
ui::test::PollingStateObserver<std::u16string_view>,
kPolledTextfieldContent);
}
class SyncPassphraseDialogBrowserTest : public InteractiveBrowserTest {
public:
SyncPassphraseDialogBrowserTest() = default;
// Sets the password and waits for the state to be propagated.
// `kPolledTextfieldContent` must be initialized with `PollState()` before
// this can be used.
MultiStep SetPassordText(std::u16string_view text) {
return Steps(EnterText(kTextFieldName, std::u16string(text)),
WaitForState(kPolledTextfieldContent, text));
}
protected:
const std::string kTextFieldName = "Texfield";
const std::string kFooterLabelName = "FooterLabel";
};
IN_PROC_BROWSER_TEST_F(SyncPassphraseDialogBrowserTest, PixelTest) {
const std::u16string_view kPassphrase = u"Passphrase";
base::MockRepeatingCallback<bool(std::u16string_view)> decrypt_callback;
Browser* browser_ptr = browser();
views::Textfield* textfield = nullptr;
// Reject the first passphrase, and accept the second.
EXPECT_CALL(decrypt_callback, Run(kPassphrase))
.WillOnce(testing::Return(false))
.WillOnce(testing::Return(true));
RunTestSequence(
// Show the dialog.
Do([&decrypt_callback, browser_ptr] {
ShowSyncPassphraseDialog(*browser_ptr, decrypt_callback.Get());
}),
WaitForShow(kSyncPassphraseOkButtonFieldId),
// Check that the button is initially disabled.
WaitForViewProperty(kSyncPassphraseOkButtonFieldId, views::View, Enabled,
false),
SetOnIncompatibleAction(OnIncompatibleAction::kIgnoreAndContinue,
"Screenshot not supported in all test modes."),
ScreenshotSurface(kSyncPassphraseOkButtonFieldId, "InitialState",
"5838370"),
// Find the underlying `views::Textfield` and track its state.
NameDescendantViewByType<views::Textfield>(kSyncPassphrasePasswordFieldId,
kTextFieldName),
WithView(kTextFieldName,
[&textfield](views::Textfield* t) {
CHECK(t);
textfield = t;
}),
PollState(kPolledTextfieldContent,
[&textfield]() { return textfield->GetText(); }),
// Enter some text, the button is enabled.
SetPassordText(kPassphrase),
WaitForViewProperty(kSyncPassphraseOkButtonFieldId, views::View, Enabled,
true),
ScreenshotSurface(kSyncPassphraseOkButtonFieldId, "WithText", "5838370"),
// Submit wrong passphrase, field is cleared and button disabled again.
PressButton(kSyncPassphraseOkButtonFieldId),
WaitForState(kPolledTextfieldContent, std::u16string()),
WaitForViewProperty(kSyncPassphraseOkButtonFieldId, views::View, Enabled,
false),
ScreenshotSurface(kSyncPassphraseOkButtonFieldId, "Invalid", "5838370"),
// Submit correct passphrase, the dialog closes.
SetPassordText(kPassphrase), PressButton(kSyncPassphraseOkButtonFieldId),
WaitForHide(kSyncPassphraseOkButtonFieldId));
}
IN_PROC_BROWSER_TEST_F(SyncPassphraseDialogBrowserTest, FooterLink) {
Browser* browser_ptr = browser();
RunTestSequence(
// Show the dialog.
Do([browser_ptr] {
ShowSyncPassphraseDialog(
*browser_ptr,
base::BindRepeating([](std::u16string_view) { return false; }));
}),
WaitForShow(kSyncPassphraseOkButtonFieldId),
// Find the footer link.
NameViewRelative(kSyncPassphraseOkButtonFieldId, kFooterLabelName,
[](views::View* ok_button) {
return ok_button->GetWidget()
->widget_delegate()
->AsDialogDelegate()
->GetFootnoteViewForTesting();
}),
// Click the link.
WithView(kFooterLabelName,
[](views::StyledLabel* footnote) {
footnote->ClickFirstLinkForTesting();
}),
// Dialog closes.
WaitForHide(kFooterLabelName));
// The sync settings page is open and active.
GURL active_url =
browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL();
EXPECT_TRUE(
base::StartsWith(active_url.spec(), chrome::kSyncGoogleDashboardURL))
<< "active_url: " << active_url;
}