]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/dashboard: E2E Tests for Create, Edit, Delete, and Invalid Input on RGW Buckets
authorRafael Quintero <rafaelq@bu.edu>
Thu, 11 Jul 2019 18:19:44 +0000 (14:19 -0400)
committerRafael Quintero <rafaelq@bu.edu>
Tue, 16 Jul 2019 11:11:22 +0000 (07:11 -0400)
Fixes: https://tracker.ceph.com/issues/40372
Fixes: https://tracker.ceph.com/issues/40484
Fixes: https://tracker.ceph.com/issues/40259
Signed-off-by: Adam King <adking@redhat.com>
Signed-off-by: Rafael Quintero <rquinter@redhat.com>
src/pybind/mgr/dashboard/frontend/e2e/helper.po.ts
src/pybind/mgr/dashboard/frontend/e2e/page-helper.po.ts
src/pybind/mgr/dashboard/frontend/e2e/rgw/buckets.e2e-spec.ts
src/pybind/mgr/dashboard/frontend/e2e/rgw/buckets.po.ts

index 3e95ff8224e0614cc48f30f1fd2c0a122e96aea0..1dcdf5862f37acb0d48d18b2f007d12c68ca6e95 100644 (file)
@@ -1,8 +1,15 @@
 import { browser } from 'protractor';
+import { BucketsPageHelper } from './rgw/buckets.po';
 
 export class Helper {
   static EC = browser.ExpectedConditions;
-  static TIMEOUT = 10000;
+  static TIMEOUT = 30000;
+
+  buckets: BucketsPageHelper;
+
+  constructor() {
+    this.buckets = new BucketsPageHelper();
+  }
 
   /**
    * Checks if there are any errors on the browser
index 7212d6b764b4e9c77a723eb1faa9b5ab7be04b77..e0d9353220db6105edad3f6362918741daa360e2 100644 (file)
@@ -1,4 +1,4 @@
-import { $, $$, browser } from 'protractor';
+import { $, $$, browser, by, element } from 'protractor';
 
 interface Pages {
   index: string;
@@ -17,11 +17,49 @@ export abstract class PageHelper {
       .getText();
   }
 
+  static getTableCount() {
+    return $('.datatable-footer-inner.selected-count');
+  }
+
+  static getTitleText() {
+    let title;
+    return browser
+      .wait(() => {
+        title = $('.panel-title');
+        return title.isPresent();
+      })
+      .then(() => title.getText());
+  }
+
+  static getTableCell(content) {
+    return element(by.cssContainingText('.datatable-body-cell-label', content));
+  }
+
+  static getTable() {
+    return element.all(by.css('.datatable-body'));
+  }
+
   static getTabsCount() {
     return $$('.nav.nav-tabs li').count();
   }
 
+  static getFirstTableCellWithText(content) {
+    return element.all(by.cssContainingText('.datatable-body-cell-label', content)).first();
+  }
+
+  // Used for instances where a modal container recieved the click rather than the
+  // desired element
+  static moveClick(object) {
+    return browser
+      .actions()
+      .mouseMove(object)
+      .click()
+      .perform();
+  }
+
   navigateTo(page = null) {
-    return browser.get(this.pages[page || 'index']);
+    page = page || 'index';
+    const url = this.pages[page];
+    return browser.get(url);
   }
 }
index ee74217318b08ac361f26d9961fd2aa29789f20f..d6685f4541c71ab8415959a221a1997531783273 100644 (file)
@@ -1,11 +1,11 @@
 import { Helper } from '../helper.po';
-import { BucketsPage } from './buckets.po';
+import { PageHelper } from '../page-helper.po';
 
 describe('RGW buckets page', () => {
-  let page: BucketsPage;
+  let buckets;
 
   beforeAll(() => {
-    page = new BucketsPage();
+    buckets = new Helper().buckets;
   });
 
   afterEach(() => {
@@ -14,11 +14,48 @@ describe('RGW buckets page', () => {
 
   describe('breadcrumb test', () => {
     beforeAll(() => {
-      page.navigateTo();
+      buckets.navigateTo();
     });
 
     it('should open and show breadcrumb', () => {
-      expect(BucketsPage.getBreadcrumbText()).toEqual('Buckets');
+      expect(PageHelper.getBreadcrumbText()).toEqual('Buckets');
+    });
+  });
+
+  describe('create, edit & delete bucket test', () => {
+    beforeAll(() => {
+      buckets.navigateTo();
+    });
+
+    it('should create bucket', () => {
+      buckets.create('000test', '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef');
+      expect(PageHelper.getTableCell('000test').isPresent()).toBe(true);
+    });
+
+    it('should edit bucket', () => {
+      buckets.edit('000test', 'dev');
+      expect(PageHelper.getTable().getText()).toMatch('dev');
+    });
+
+    it('should delete bucket', () => {
+      buckets.delete('000test');
+      expect(PageHelper.getTableCell('000test').isPresent()).toBe(false);
+    });
+  });
+
+  describe('Invalid Input in Create and Edit tests', () => {
+    beforeAll(() => {
+      buckets.navigateTo();
+    });
+
+    it('should test invalid inputs in create fields', () => {
+      buckets.invalidCreate();
+    });
+
+    it('should test invalid input in edit owner field', () => {
+      buckets.create('000rq', '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef');
+      buckets.invalidEdit('000rq');
+      buckets.delete('000rq');
     });
   });
 });
index 5341f7520c4ce8a4105c093b01e77b81bbfe63e4..3506a019075af6ad290390fd233cce8437e16586 100644 (file)
@@ -1,5 +1,186 @@
+import { $, browser, by, element } from 'protractor';
+import { Helper } from '../helper.po';
 import { PageHelper } from '../page-helper.po';
 
-export class BucketsPage extends PageHelper {
-  pages = { index: '/#/rgw/bucket' };
+export class BucketsPageHelper extends PageHelper {
+  pages = {
+    index: '/#/rgw/bucket',
+    create: '/#/rgw/bucket/create'
+  };
+
+  create(name, owner) {
+    this.navigateTo('create');
+
+    // Enter in bucket name
+    element(by.id('bid')).sendKeys(name);
+
+    // Select bucket owner
+    element(by.id('owner')).click();
+    element(by.cssContainingText('select[name=owner] option', owner)).click();
+    expect(element(by.id('owner')).getAttribute('class')).toContain('ng-valid');
+
+    // Click the create button and wait for bucket to be made
+    const createButton = element(by.cssContainingText('button', 'Create Bucket'));
+    createButton.click().then(() => {
+      browser.wait(
+        Helper.EC.presenceOf(PageHelper.getTableCell(name)),
+        Helper.TIMEOUT,
+        'Timed out waiting for bucket creation'
+      );
+    });
+  }
+
+  edit(name, new_owner) {
+    this.navigateTo();
+
+    browser.wait(Helper.EC.elementToBeClickable(PageHelper.getTableCell(name)), 10000); // wait for table to load
+    PageHelper.getTableCell(name).click(); // click on the bucket you want to edit in the table
+    element(by.cssContainingText('button', 'Edit')).click(); // click button to move to edit page
+
+    expect(PageHelper.getBreadcrumbText()).toEqual('Edit');
+
+    const ownerDropDown = element(by.id('owner'));
+    ownerDropDown.click(); // click owner dropdown menu
+
+    element(by.cssContainingText('select[name=owner] option', new_owner)).click(); // select the new user
+    const editbutton = element(by.cssContainingText('button', 'Edit Bucket'));
+    editbutton.click().then(() => {
+      // wait to be back on buckets page with table visible
+      browser.wait(
+        Helper.EC.elementToBeClickable(PageHelper.getTableCell(name)),
+        10000,
+        'Could not return to buckets page and load table after editing bucket'
+      );
+
+      // click on edited bucket and check its details table for edited owner field
+      PageHelper.getTableCell(name).click();
+      const element_details_table = element
+        .all(by.css('.table.table-striped.table-bordered'))
+        .first();
+      expect(element_details_table.getText()).toMatch(new_owner);
+    });
+  }
+
+  delete(name) {
+    this.navigateTo();
+
+    // wait for table to load
+    browser.wait(Helper.EC.elementToBeClickable(PageHelper.getTableCell(name)), 10000);
+
+    PageHelper.getTableCell(name).click(); // click on the bucket you want to delete in the table
+    $('.table-actions button.dropdown-toggle').click(); // click toggle menu
+    $('li.delete a').click(); // click delete
+    // wait for pop-up to be visible (checks for title of pop-up)
+    browser.wait(Helper.EC.visibilityOf($('.modal-title.float-left')), 10000).then(() => {
+      browser.wait(Helper.EC.visibilityOf($('.custom-control-label')), 5000);
+      $('.custom-control-label').click();
+      element(by.cssContainingText('button', 'Delete bucket'))
+        .click()
+        .then(() => {
+          this.navigateTo();
+          browser.wait(Helper.EC.not(Helper.EC.presenceOf(PageHelper.getTableCell(name))), 10000);
+        });
+    });
+  }
+
+  invalidCreate() {
+    this.navigateTo('create');
+    expect(PageHelper.getBreadcrumbText()).toEqual('Create');
+
+    const nameInputField = element(by.id('bid')); // Grabs name box field
+    const ownerDropDown = element(by.id('owner')); // Grab owner field
+
+    // Gives an invalid name (too short), then waits for dashboard to determine validity
+    nameInputField.sendKeys('rq');
+
+    PageHelper.moveClick(ownerDropDown); // To trigger a validation
+
+    browser.wait(
+      function() {
+        // Waiting for website to decide if name is valid or not
+        return nameInputField.getAttribute('class').then(function(classValue) {
+          return classValue.indexOf('ng-pending') === -1;
+        });
+      },
+      5000,
+      'Timed out waiting for dashboard to decide bucket name validity'
+    );
+
+    // Check that name input field was marked invalid in the css
+    expect(nameInputField.getAttribute('class')).toContain('ng-invalid');
+
+    // Check that error message was printed under name input field
+    expect(element(by.css('#bid + .invalid-feedback')).getText()).toMatch(
+      'The value is not valid.'
+    );
+
+    // Test invalid owner input
+    PageHelper.moveClick(ownerDropDown); // Clicks the Owner drop down on the Create Bucket page
+    // select some valid option. The owner drop down error message will not appear unless a valid user was selected at
+    // one point before the invalid placeholder user is selected.
+    element(by.cssContainingText('select[name=owner] option', 'dev')).click();
+
+    PageHelper.moveClick(ownerDropDown); // Clicks the Owner drop down on the Create Bucket page
+    // select the first option, which is invalid because it is a placeholder
+    element(by.cssContainingText('select[name=owner] option', 'Select a user')).click();
+
+    PageHelper.moveClick(nameInputField); // To trigger a validation
+
+    // Check that owner drop down field was marked invalid in the css
+    expect(element(by.id('owner')).getAttribute('class')).toContain('ng-invalid');
+
+    // Check that error message was printed under owner drop down field
+    expect(element(by.css('#owner + .invalid-feedback')).getText()).toMatch(
+      'This field is required.'
+    );
+
+    // Clicks the Create Bucket button but the page doesn't move. Done by testing
+    // for the breadcrumb
+    PageHelper.moveClick(element(by.cssContainingText('button', 'Create Bucket'))); // Clicks Create Bucket button
+    expect(PageHelper.getBreadcrumbText()).toEqual('Create');
+    // content in fields seems to subsist through tests if not cleared, so it is cleared
+    nameInputField.clear().then(() => {
+      element(by.cssContainingText('button', 'Cancel')).click();
+    });
+  }
+
+  invalidEdit(name) {
+    this.navigateTo();
+
+    browser.wait(
+      Helper.EC.elementToBeClickable(PageHelper.getTableCell(name)),
+      10000,
+      'Failed waiting for bucket to be present in table'
+    ); // wait for table to load
+    PageHelper.getTableCell(name).click(); // click on the bucket you want to edit in the table
+    element(by.cssContainingText('button', 'Edit')).click(); // click button to move to edit page
+
+    expect(PageHelper.getBreadcrumbText()).toEqual('Edit');
+
+    // Chooses 'Select a user' rather than a valid owner on Edit Bucket page
+    // and checks if it's an invalid input
+    const ownerDropDown = element(by.id('owner'));
+    browser.wait(Helper.EC.elementToBeClickable(ownerDropDown), 5000);
+
+    PageHelper.moveClick(ownerDropDown); // Clicks the Owner drop down on the Create Bucket page
+    // select the first option, which is invalid because it is a placeholder
+    element(by.cssContainingText('select[name=owner] option', 'Select a user')).click();
+
+    // Changes when updated to bootstrap 4 -> Error message takes a long time to appear unless another field
+    // is clicked on. For that reason, I'm having the test click on the nedit button before checking for errors
+    element(by.cssContainingText('button', 'Edit Bucket')).click();
+
+    // Check that owner drop down field was marked invalid in the css
+    expect(element(by.id('owner')).getAttribute('class')).toContain('ng-invalid');
+
+    // Check that error message was printed under owner drop down field
+    expect(element(by.css('#owner + .invalid-feedback')).getText()).toMatch(
+      'This field is required.'
+    );
+
+    // Clicks the Edit Bucket button but the page doesn't move. Done by testing for
+    // breadcrumb
+    element(by.cssContainingText('button', 'Edit Bucket')).click(); // Gets the Edit button and clicks it
+    expect(PageHelper.getBreadcrumbText()).toEqual('Edit');
+  }
 }