chromium/chrome/test/data/webui/chromeos/personalization_app/sea_pen_freeform_element_test.ts

// 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.

import 'chrome://personalization/strings.m.js';

import {SeaPenFreeformElement, SeaPenImagesElement, SeaPenRecentWallpapersElement, SeaPenSamplesElement, setTransitionsEnabled, WallpaperGridItemElement} from 'chrome://personalization/js/personalization_app.js';
import {CrButtonElement} from 'chrome://resources/ash/common/cr_elements/cr_button/cr_button.js';
import {MantaStatusCode} from 'chrome://resources/ash/common/sea_pen/sea_pen.mojom-webui.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {assert} from 'chrome://webui-test/chai.js';
import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';

import {baseSetup, initElement, teardownElement} from './personalization_app_test_utils.js';
import {TestPersonalizationStore} from './test_personalization_store.js';
import {TestSeaPenProvider} from './test_sea_pen_interface_provider.js';

suite('SeaPenFreeformElementTest', function() {
  let freeformElement: SeaPenFreeformElement|null = null;
  let personalizationStore: TestPersonalizationStore;
  let seaPenProvider: TestSeaPenProvider;

  function getSamples(): string[] {
    const seaPenSamplesElement =
        freeformElement!.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    const samples = seaPenSamplesElement!.shadowRoot!
                        .querySelectorAll<WallpaperGridItemElement>(
                            `${WallpaperGridItemElement.is}:not([hidden])`);
    assertTrue(!!samples, 'samples should exist');

    return Array.from(samples).flatMap(sample => {
      const text =
          sample!.shadowRoot!.querySelector('.primary-text')?.innerHTML;
      return text ? [text] : [];
    });
  }

  setup(() => {
    loadTimeData.overrideValues(
        {isSeaPenEnabled: true, isSeaPenTextInputEnabled: true});
    const mocks = baseSetup();
    personalizationStore = mocks.personalizationStore;
    seaPenProvider = mocks.seaPenProvider;

    // Disables page transition by default.
    setTransitionsEnabled(false);
  });

  teardown(async () => {
    await teardownElement(freeformElement);
    freeformElement = null;
  });

  test('shows default freeform page without tab container', async () => {
    // Initialize |freeformElement|.
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    assertTrue(
        !!freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is),
        'sample prompts element shown on freeform page');

    assertFalse(
        !!freeformElement.shadowRoot!.querySelector('#tabContainer'),
        'tab container is not shown');
    assertTrue(
        !!freeformElement.shadowRoot!.querySelector('#promptingGuide'),
        'Prompting guide is shown');
    assertTrue(
        !!freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is),
        'sea-pen-samples shown on freeform page');
    assertTrue(
        !!freeformElement.shadowRoot!.querySelector(
            SeaPenRecentWallpapersElement.is),
        'sea-pen-recent-wallpapers shown on freeform page');
    assertTrue(
        !!freeformElement!.shadowRoot!.getElementById('shuffle'),
        'shuffle button should be shown');
    assertTrue(
        !!freeformElement!.shadowRoot!.getElementById('promptingGuide'),
        'prompting guide should exist');

    assertFalse(
        !!freeformElement.shadowRoot!.querySelector<HTMLElement>(
            SeaPenImagesElement.is),
        'sea-pen-images is not shown');
  });

  test('shows 6 sample prompts in freeform freeform page', async () => {
    // Initialize |freeformElement|.
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    const samplesElement =
        freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    await waitAfterNextRender(samplesElement as HTMLElement);

    assertTrue(
        !!samplesElement, 'sample prompts element shown on freeform page');
    assertEquals(6, getSamples().length, 'there are 6 sample prompts');
  });

  test('shows freeform page with tab container', async () => {
    personalizationStore.data.wallpaper.seaPen.currentSeaPenQuery =
        seaPenProvider.seaPenFreeformQuery;

    // Initialize |freeformElement|.
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    const tabContainer =
        freeformElement.shadowRoot!.querySelector('#tabContainer');
    assertTrue(!!tabContainer, 'tab container displays');

    // Sample prompts tab should be present and but not pressed.
    const samplePromptsTabButton =
        tabContainer!.querySelector<CrButtonElement>('#samplePromptsTab');
    assertTrue(!!samplePromptsTabButton, 'sample prompts tab displays');
    assertEquals(samplePromptsTabButton.getAttribute('aria-pressed'), 'false');

    // Results tab should be present and pressed.
    const resultsTabButton =
        tabContainer!.querySelector<CrButtonElement>('#resultsTab');
    assertTrue(!!resultsTabButton, 'results tab display');
    assertEquals(resultsTabButton.getAttribute('aria-pressed'), 'true');

    assertFalse(
        !!freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is),
        'sea-pen-samples is not shown');

    assertFalse(
        !!freeformElement.shadowRoot!.querySelector(
            SeaPenRecentWallpapersElement.is),
        'sea-pen-recent-wallpapers is not shown');
    assertFalse(
        !!freeformElement!.shadowRoot!.getElementById('shuffle'),
        'shuffle button should be hidden for results tab');
    assertFalse(
        !!freeformElement!.shadowRoot!.getElementById('promptingGuide'),
        'prompting guide should be hidden for results tab');

    assertTrue(
        !!freeformElement.shadowRoot!.querySelector<HTMLElement>(
            SeaPenImagesElement.is),
        'sea-pen-images is shown');
  });

  test('switches tab in freeform page', async () => {
    personalizationStore.data.wallpaper.seaPen.currentSeaPenQuery =
        seaPenProvider.seaPenFreeformQuery;

    // Initialize |freeformElement|.
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    const tabContainer =
        freeformElement.shadowRoot!.querySelector('#tabContainer');
    assertTrue(!!tabContainer, 'tab container displays');

    // Switch to Sample Prompts tab
    const samplePromptsTabButton =
        tabContainer!.querySelector<CrButtonElement>('#samplePromptsTab');
    samplePromptsTabButton!.click();
    await waitAfterNextRender(freeformElement);

    assertTrue(
        !!freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is),
        'sea-pen-samples is shown in Sample Prompts tab');
    assertTrue(
        !!freeformElement.shadowRoot!.querySelector(
            SeaPenRecentWallpapersElement.is),
        'sea-pen-recent-wallpapers is shown in Sample Prompts tab');
    assertTrue(
        !!freeformElement!.shadowRoot!.getElementById('shuffle'),
        'shuffle button should be shown for samples tab');
    assertTrue(
        !!freeformElement!.shadowRoot!.getElementById('promptingGuide'),
        'prompting guide should be shown for samples tab');
    assertFalse(
        !!freeformElement.shadowRoot!.querySelector<HTMLElement>(
            SeaPenImagesElement.is),
        'sea-pen-images is not shown');
  });

  test('shuffles samples', async () => {
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    let seaPenSamplesElement =
        freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    await waitAfterNextRender(seaPenSamplesElement as HTMLElement);
    assertTrue(!!seaPenSamplesElement, 'sea-pen-samples is visible');
    const originalSamples = getSamples();

    // Click shuffle button
    const shuffleButton =
        freeformElement!.shadowRoot!.getElementById('shuffle');
    shuffleButton!.click();
    await waitAfterNextRender(freeformElement);
    seaPenSamplesElement =
        freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    await waitAfterNextRender(seaPenSamplesElement as HTMLElement);

    assert.notSameOrderedMembers(
        originalSamples, getSamples(), 'the order should be different');
  });

  test('shuffles samples with tab', async () => {
    personalizationStore.data.wallpaper.seaPen.currentSeaPenQuery =
        seaPenProvider.seaPenFreeformQuery;
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);
    const tabContainer =
        freeformElement.shadowRoot!.querySelector('#tabContainer');

    // Switch to Sample Prompts tab
    const samplePromptsTabButton =
        tabContainer!.querySelector<CrButtonElement>('#samplePromptsTab');
    samplePromptsTabButton!.click();
    await waitAfterNextRender(freeformElement);
    let seaPenSamplesElement =
        freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    await waitAfterNextRender(seaPenSamplesElement as HTMLElement);
    assertTrue(
        !!seaPenSamplesElement,
        'sea-pen-samples is shown in Sample Prompts tab');
    const originalSamples = getSamples();

    // Click shuffle button
    const shuffleButton =
        freeformElement!.shadowRoot!.getElementById('shuffle');
    shuffleButton!.click();
    await waitAfterNextRender(freeformElement);
    seaPenSamplesElement =
        freeformElement.shadowRoot!.querySelector(SeaPenSamplesElement.is);
    await waitAfterNextRender(seaPenSamplesElement as HTMLElement);

    assert.notSameOrderedMembers(
        originalSamples, getSamples(), 'the order should be different');
  });

  test('shows results page for errors', async () => {
    personalizationStore.data.wallpaper.seaPen.thumbnailResponseStatusCode =
        MantaStatusCode.kGenericError;
    freeformElement = initElement(SeaPenFreeformElement);
    await waitAfterNextRender(freeformElement);

    // Results tab should be present and pressed.
    const tabContainer =
        freeformElement.shadowRoot!.querySelector('#tabContainer');
    assertTrue(!!tabContainer, 'tab container should exist');
    const resultsTabButton =
        tabContainer!.querySelector<CrButtonElement>('#resultsTab');
    assertTrue(!!resultsTabButton, 'results tab displays');
    assertEquals(
        'true', resultsTabButton.getAttribute('aria-pressed'),
        'results tab is pressed');
    assertTrue(
        !!freeformElement.shadowRoot!.querySelector<HTMLElement>(
            SeaPenImagesElement.is),
        'sea-pen-images is shown');
  });
});