Home Manual Reference Source

src/page_objects/web/contacts/pages/base.contacts.page.js

import * as _ from "lodash";
import BasePage from "../../../base.page.js";
import NavPanel from "../../general/nav.panel.js";

/** 
 * BaseContactsPage 
 * @extends BasePage
 */
class BaseContactsPage extends BasePage {
  /**
   * @param {args} args Args from controller
   */
  constructor(args) {
    super(args);
    this.navPanel = new NavPanel(args);
  }

  // PAGE ELEMENTS
  /* eslint-disable require-jsdoc, max-len */
  showDropdown() {
    return this.element(
      "div[class^=components-Contacts-Contacts__contactFilterDropdown]"
    );
  }

  dropdownItems() {
    return this.element(
      "button[class^=components-Contacts-Contacts__dropdownAutoWidth]"
    );
  }

  showAllButton() {
    return this.element("span=All");
  }

  showAvailableButton() {
    return this.element("span=Available");
  }

  contactsListContainer() {
    return this.element("div#contactsListContainer");
  }

  contactsListItems() {
    return this.elements(
      "div#contactsListContainer div.iconsize-list div[class^=components-Contacts-ContactListItem__overflowContainer]"
    );
  }

  contactPresence() {
    return this.element("div.statusIcon");
  }

  contactNamed(name) {
    return this.element(`div=${name}`);
  }

  noContactsMessage() {
    return this.element("div[class^=components-Contacts-Contacts__noContacts]");
  }

  /* eslint-enable require-jsdoc */

  // PAGE FUNCTIONS

  /**
   * Internal method to find contact element
   * @param {String} name Name of contact
   * @returns {Element} Element of contact
   */
  async findContact(name) {
    await this.scrollContactsListContainerToTop();
    return await this._findContact(name);
  }

  /* eslint-disable max-statements */
  /**
   * Internal method to find contact element
   * @param {String} name Name of contact
   * @returns {Element} Element of contact
   */
  async _findContact(name) {
    const contact = this.contactNamed(name);
    const isVisible = await contact.isVisible();

    if (isVisible === false) {
      const visibleContacts = await this.getVisibleContactsList();
      const bottomContact = visibleContacts[visibleContacts.length - 1];
      const scrollTop = await this.getScrollTop();
      await this.scrollToContact(bottomContact);
      const newScrollTop = await this.getScrollTop();

      if (scrollTop.value === newScrollTop.value) {
        return null; // Contact is not in list
      } else {
        await this._findContact(name);
      }
    } else {
      return contact;
    }
  }
  /* eslint-enable max-statements */

  /**
   * Get scrolltop value for contactsListContainen
   * @returns {Integer} Value of scrolltop
   */
  async getScrollTop() {
    return await this.browser.execute(() => {
      var element = document.getElementById("contactsListContainer"); // eslint-disable-line
      var scrollTop = element.scrollTop; // eslint-disable-line
      return scrollTop;
    });
  }

  /** Gets the contacts list items on page
   * @returns {Array} Array of the divs of the contacts list
   * @todo Optimize this. It's slow.
   */
  async getVisibleContactsList() {
    await this.contactsListContainer().waitForVisible();
    return await this.contactsListItems().all();
  }

  /**
   * Scrolls to contact.
   * @param {String} contact Contact element
   * @param {Integer} additionalOffset Amount of additional pixels to scroll
   */
  async scrollToContact(contact, additionalOffset = 0) {
    const attribute = await contact.getAttribute("offsetTop");
    const offset = attribute + additionalOffset;
    await this.browser.execute(offset => {
      var element = document.getElementById("contactsListContainer"); // eslint-disable-line
      element.scrollTop = offset; // eslint-disable-line
    }, offset);
    // pause to wait for scroll to complete
    await this.pause(1000);
  }

  /**
   * Scrolls contactListContainer to the top
   */
  async scrollContactsListContainerToTop() {
    await this.browser.execute(() => {
      var element = document.getElementById("contactsListContainer"); // eslint-disable-line
      element.scrollTop = 0; // eslint-disable-line
    });
    await this.pause(2000);
  }

  /** Click on contact with provided name
   * @param {String} name Name of contact to select
  */
  async selectContact(name) {
    const contact = await this.findContact(name);
    await contact.hover();
    await this.browser.pause(1000);
    await contact.click();
  }

  /**
  * Finds if the contact has a chat option on the contact container 
  * @param {String}  name of Contact
  * @returns {Boolean} True if Chat element found  and False if Not 
  */
  async chatIconPresent(name) {
    const contactElement = await this.findContact(name);
    await contactElement.hover();
    await this.browser.pause(1000);
    const listButton = this.element(
      `//div[contains(string(),'${name}') and contains(@class,'iconsize-list')]//button[contains(@class,'icon-chat')]`
    );
    const chatTrue = await listButton.isVisible();
    return chatTrue;
  }

  /**
   * Click on the filter dropdown to show it
   */
  async showFilterOptions() {
    await this.showDropdown().click();
    await this.browser.pause(1000);
  }

  /**
   * Get names in current list
   * @param {Array} namesList Array of names
   * @returns {Array} Array of names
   */
  async getNamesInList(namesList = []) {
    const visibleContacts = await this.getVisibleContactsList();

    Promise.all(
      _.forEach(visibleContacts, async contact => {
        const name = await contact.getText();
        namesList.push(name);
      })
    );

    // Scroll and check to see if at the bottom
    const bottomContact = visibleContacts[visibleContacts.length - 1];
    const scrollTop = await this.getScrollTop();
    await this.scrollToContact(bottomContact);
    const newScrollTop = await this.getScrollTop();

    if (scrollTop.value === newScrollTop.value) {
      return namesList; // Contact is not in list
    } else {
      await this.getNamesInList(namesList);
    }
  }
}

export default BaseContactsPage;