<%#
 Copyright 2013-2021 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      https://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
/* tslint:disable no-unused-expression */
import { browser<% if ( fieldsContainInstant || fieldsContainZonedDateTime ) { %>, protractor<% } %>} from 'protractor';

import NavBarPage from './../../<%= entityParentPathAddition %>page-objects/navbar-page';
import <%= entityClass %>ComponentsPage, { <%= entityClass %>DeleteDialog } from './<%= entityFileName %>.page-object';
<%_ if (!readOnly) { _%>
import <%= entityClass %>UpdatePage from './<%= entityFileName%>-update.page-object';
<%_ } _%>
import <%= entityClass %>DetailsPage from './<%= entityFileName%>-details.page-object';

import {
  clear,
  click,
  getRecordsCount,
  isVisible,
  selectLastOption,
  waitUntilAllDisplayed,
  waitUntilAnyDisplayed,
  waitUntilCount,
  waitUntilDisplayed,
  waitUntilHidden
} from '../../<%= entityParentPathAddition %>util/utils';

<%_ if (fieldsContainBlobOrImage) { _%>
import path from 'path';
<%_ } _%>
<%_
let elementGetter = `getText()`;
let openBlockComment = ``;
let closeBlockComment = ``;
if (enableTranslation) {
    elementGetter = `getAttribute('jhiTranslate')`;
}
for (let relationship of relationships) {
    if (relationship.relationshipRequired || relationship.id) {
        openBlockComment = `/*`;
        closeBlockComment = `*/`;
        break;
    }
} _%>

const expect = chai.expect;

describe('<%= entityClass %> e2e test', () => {
  let navBarPage: NavBarPage;
  <%_ if (!readOnly) { _%>
  let updatePage: <%= entityClass %>UpdatePage;
  <%_ } _%>
  let detailsPage: <%= entityClass %>DetailsPage;
  let listPage: <%= entityClass %>ComponentsPage;
  <%= openBlockComment %>let deleteDialog: <%= entityClass %>DeleteDialog;<%= closeBlockComment %>
  <%_ if (fieldsContainBlobOrImage) { _%>
  const fileToUpload = '../../../../../<%= entityParentPathAddition %>main/webapp/content/images/logo-jhipster.png';
  const absolutePath = path.resolve(__dirname, fileToUpload);
  <%_ } _%>
  let beforeRecordsCount = 0;
  const username = process.env.E2E_USERNAME ?? 'admin';
  const password = process.env.E2E_PASSWORD ?? 'admin';

  before(async () => {
    await browser.get('/');
    navBarPage = new NavBarPage();
    await navBarPage.login(username, password);
  });


  after(async () => {
    await navBarPage.autoSignOut();
  });

  it('should load <%= entityClassPlural %>', async () => {
    await navBarPage.getEntityPage('<%= entityStateName %>');
    listPage = new <%= entityClass %>ComponentsPage();

    await waitUntilAllDisplayed([listPage.title, listPage.footer]);

    expect(await listPage.title.getText()).not.to.be.empty;
    <%_ if (!readOnly) { _%>
    expect(await listPage.createButton.isEnabled()).to.be.true;
    <%_ } _%>

    await waitUntilAnyDisplayed([listPage.noRecords, listPage.table]);
    beforeRecordsCount = await isVisible(listPage.noRecords) ? 0 : await getRecordsCount(listPage.table);
  });
<%_ if (!readOnly) { _%>
  describe('Create flow', () => {
    it('should load create <%= entityClass %> page', async () => {

      await listPage.createButton.click();
      updatePage = new <%= entityClass %>UpdatePage();

      await waitUntilAllDisplayed([updatePage.title, updatePage.footer, updatePage.saveButton]);

      <%_ if (enableTranslation) { _%>
      expect(await updatePage.title.getAttribute('id'))
        .to.match(/<%= i18nKeyPrefix %>.home.createOrEditLabel/);
      <%_ } else { _%>
      expect(await updatePage.title.getText())
        .to.match(/Create or edit a <%= entityClass %>/);
      <%_ } _%>
    });

   <%= openBlockComment %> it('should create and save <%= entityClassPlural %>', async () => {
      <%_ fields.filter(field => !field.id).forEach((field) => {
        const fieldName = field.fieldName;
        const fieldNameCapitalized = field.fieldNameCapitalized;
        const fieldType = field.fieldType;
        const fieldTypeBlobContent = field.fieldTypeBlobContent;
        const fieldIsEnum = field.fieldIsEnum;
        const fieldValidateSampleString = field.fieldValidateSampleString;
      _%>

      <%_ if (['Integer', 'Long', 'Float', 'Double', 'BigDecimal'].includes(fieldType)) { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('5');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('5');

      <%_ } else if (fieldType === 'LocalDate') { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('2001-01-01');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('2001-01-01');

      <%_ } else if (['Instant', 'ZonedDateTime'].includes(fieldType)) { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('01/01/2001' + protractor.Key.TAB + '02:30AM');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.contain('2001-01-01T02:30');

      <%_ } else if (fieldType === 'Duration') { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('PT12S');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.contain('PT12S');

      <%_ } else if (fieldType === 'Boolean') { _%>
      const selected<%= fieldNameCapitalized %> = await updatePage.<%= fieldName %>Input.isSelected();
      if (selected<%= fieldNameCapitalized %>) {
        await updatePage.<%= fieldName %>Input.click();
        expect(await updatePage.<%= fieldName %>Input.isSelected()).to.be.false;
      } else {
        await updatePage.<%= fieldName %>Input.click();
        expect(await updatePage.<%= fieldName %>Input.isSelected()).to.be.true;
      }

      <%_ } else if (['byte[]', 'ByteBuffer'].includes(fieldType) && fieldTypeBlobContent === 'text') { _%>
      await waitUntilDisplayed(updatePage.<%= fieldName %>Input);
      await updatePage.<%= fieldName %>Input.sendKeys('<%= fieldName %>');

      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/<%= fieldName %>/);

      <%_ } else if (['byte[]', 'ByteBuffer'].includes(fieldType)) { _%>
      await waitUntilDisplayed(updatePage.<%= fieldName %>Input);
      await updatePage.<%= fieldName %>Input.sendKeys(absolutePath);

      <%_ } else if (fieldIsEnum) { _%>
      await selectLastOption(updatePage.<%= fieldName %>Select);

      <%_ } else if (fieldType === 'UUID'){ _%>
      await updatePage.<%= fieldName %>Input.sendKeys('64c99148-3908-465d-8c4a-e510e3ade974');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/64c99148-3908-465d-8c4a-e510e3ade974/);

      <%_ } else if (fieldType === 'String' && fieldValidateSampleString) { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('<%= fieldValidateSampleString %>');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('<%= fieldValidateSampleString %>');

      <%_ } else { _%>
      await updatePage.<%= fieldName %>Input.sendKeys('<%= fieldName %>');
      expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/<%= fieldName %>/);

      <%_ } _%>
      <%_ }); _%>
      <%_ relationships.forEach((relationship) => {
        const relationshipType = relationship.relationshipType;
        const ownerSide = relationship.ownerSide;
        const relationshipName = relationship.relationshipName; _%>
      <%_ if (relationshipType === 'many-to-one' || (relationshipType === 'one-to-one' && ownerSide === true)) { _%>
      // await selectLastOption(updatePage.<%= relationshipName %>Select);
      <%_ } else if ((relationshipType === 'many-to-many' && ownerSide === true)) { _%>
      // await selectLastOption(updatePage.<%= relationshipName %>Select);
      <%_ } _%>
      <%_ }); _%>

      expect(await updatePage.saveButton.isEnabled()).to.be.true;
      await updatePage.saveButton.click();

      await waitUntilHidden(updatePage.saveButton);
      expect(await isVisible(updatePage.saveButton)).to.be.false;

      await waitUntilCount(listPage.records, beforeRecordsCount + 1);
      expect(await listPage.records.count()).to.eq(beforeRecordsCount + 1);
    });<%= closeBlockComment %>

    <%= openBlockComment %>
    describe('Details, Update, Delete flow', () => {

      after(async () => {

        const deleteButton = listPage.getDeleteButton(listPage.records.<%_ if (pagination === 'infinite-scroll' || pagination === 'no') { _%>last()<%_ } else {_%>first()<%_ } _%>);
        await click(deleteButton);

        deleteDialog = new <%= entityClass %>DeleteDialog();
        await waitUntilDisplayed(deleteDialog.dialog);

        expect(await deleteDialog.title.getAttribute('id')).to.match(/<%= i18nKeyPrefix %>.delete.question/);

        await click(deleteDialog.confirmButton);
        await waitUntilHidden(deleteDialog.dialog);

        expect(await isVisible(deleteDialog.dialog)).to.be.false;

        await waitUntilCount(listPage.records, beforeRecordsCount);
        expect(await listPage.records.count()).to.eq(beforeRecordsCount);
      });

      it('should load details <%= entityClass %> page and fetch data', async () => {

        const detailsButton = listPage.getDetailsButton(listPage.records.<%_ if (pagination === 'infinite-scroll' || pagination === 'no' ) { _%>last()<%_ } else {_%>first()<%_ } _%>);
        await click(detailsButton);

        detailsPage = new <%= entityClass %>DetailsPage();

        <%_ if (fields.some(field => !field.id) && databaseType !== 'neo4j') { _%>
        await waitUntilAllDisplayed([detailsPage.title, detailsPage.backButton, detailsPage.firstDetail]);
        <%_ } else { _%>
        await waitUntilAllDisplayed([detailsPage.title, detailsPage.backButton]);
        <%_ } _%>

        expect(await detailsPage.title.getText()).not.to.be.empty;
        <%_ if (fields.some(field => !field.id) && databaseType !== 'neo4j') { _%>
        expect(await detailsPage.firstDetail.getText()).not.to.be.empty;
        <%_ } _%>

        await click(detailsPage.backButton);
        await waitUntilCount(listPage.records, beforeRecordsCount + 1);
      });

      it('should load edit <%= entityClass %> page, fetch data and update', async () => {

        const editButton = listPage.getEditButton(listPage.records.<%_ if (pagination === 'infinite-scroll' || pagination === 'no') { _%>last()<%_ } else {_%>first()<%_ } _%>);
        await click(editButton);

        await waitUntilAllDisplayed([updatePage.title, updatePage.footer, updatePage.saveButton]);

        expect(await updatePage.title.getText()).not.to.be.empty;

        <%_ fields.filter(field => !field.id).forEach((field) => {
          const fieldName = field.fieldName;
          const fieldNameCapitalized = field.fieldNameCapitalized;
          const fieldType = field.fieldType;
          const fieldTypeBlobContent = field.fieldTypeBlobContent;
          const fieldIsEnum = field.fieldIsEnum;
          const fieldValidateModifiedString = field.fieldValidateModifiedString;
        _%>
        <%_ if (['Integer', 'Long', 'Float', 'Double', 'BigDecimal'].includes(fieldType)) { _%>
          await clear(updatePage.<%= fieldName %>Input);
          await updatePage.<%= fieldName %>Input.sendKeys('6');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('6');

        <%_ } else if (fieldType === 'LocalDate') { _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('2019-01-01');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('2019-01-01');

        <%_ } else if (['Instant', 'ZonedDateTime'].includes(fieldType)) { _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('01/01/2019' + protractor.Key.TAB + '02:30AM');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.contain('2019-01-01T02:30');

        <%_ } else if (fieldType === 'Duration') { _%>
          await clear(updatePage.<%= fieldName %>Input);
          await updatePage.<%= fieldName %>Input.sendKeys('PT14S');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.contain('PT14S');

        <%_ } else if (fieldType === 'Boolean') { _%>
          const selected<%= fieldNameCapitalized %> = await updatePage.<%= fieldName %>Input.isSelected();
          if (selected<%= fieldNameCapitalized %>) {
            await updatePage.<%= fieldName %>Input.click();
            expect(await updatePage.<%= fieldName %>Input.isSelected()).to.be.false;
          } else {
            await updatePage.<%= fieldName %>Input.click();
            expect(await updatePage.<%= fieldName %>Input.isSelected()).to.be.true;
          }

        <%_ } else if (['byte[]', 'ByteBuffer'].includes(fieldType) && fieldTypeBlobContent === 'text') { _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('updated<%= fieldName %>');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/updated<%= fieldName %>/);

        <%_ } else if (fieldType === 'UUID'){ _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('64c99148-3908-465d-8c4a-e510e3ade978');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/64c99148-3908-465d-8c4a-e510e3ade978/);

        <%_ } else if (fieldType === 'String' && fieldValidateModifiedString) { _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('<%= fieldValidateModifiedString %>');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.eq('<%= fieldValidateModifiedString %>');

        <%_ } else if (!fieldIsEnum && !['byte[]', 'ByteBuffer'].includes(fieldType)) { _%>
          await updatePage.<%= fieldName %>Input.clear();
          await updatePage.<%= fieldName %>Input.sendKeys('modified');
          expect(await updatePage.<%= fieldName %>Input.getAttribute('value')).to.match(/modified/);

        <%_ } _%>
        <%_ }); _%>

        await updatePage.saveButton.click();

        await waitUntilHidden(updatePage.saveButton);

        expect(await isVisible(updatePage.saveButton)).to.be.false;
        await waitUntilCount(listPage.records, beforeRecordsCount + 1);
      });
    });
    <%= closeBlockComment %>
  });
<%_ } _%>
});
