如何使用打字稿修复'No Spec Found'错误

时间:2019-06-24 09:09:00

标签: angular typescript jasmine protractor e2e-testing

在尝试执行测试用例时,我遇到“无频谱错误”。我已经使用了通过async await包裹在自定义辅助方法中的现有量角器方法。

我尝试对规范的位置进行编辑,并尝试对规范文件进行不同的命名,但仍然没有用。

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  allScriptsTimeout: 11000,
  SELENIUM_PROMISE_MANAGER: false,
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      args: ['--disable-gpu']
    }
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 90000,
  },
  onPrepare() {
    browser.manage().window().maximize();
    browser.manage().timeouts().implicitlyWait(5000);
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { 
      displayStacktrace: 'all',
      displayPending: true, } }));
    var AllureReporter = require('jasmine-allure-reporter');
    jasmine.getEnv().addReporter(new AllureReporter({
      resultsDir: 'allure-results',
    }));
    jasmine.getEnv().afterEach(function(done){
      browser.takeScreenshot().then(function (png) {
        allure.createAttachment('Screenshot', function () {
          return new Buffer(png, 'base64')
        }, 'image/png')();
        done();
      })
    });
  },
  specs: [
    './e2e/Tests/login.spec.ts'
  ],
  onComplete() {
  },
  plugins: [
    {
      package: "protractor-console-plugin",
      failOnWarning: false,
      failOnError: true,
      logWarnings: true
    }
  ]
};

这是我当前正在使用的帮助程序类。

import { browser, by, element, error, $, ExpectedConditions, WebElement, $$, ElementArrayFinder, ElementFinder, WebElementPromise } from 'protractor';
import { Type } from './common.locator.types.enum';

export class CommonPageHelper {
    private _elementTimeOut = 10000;

    constructor(private _browser = browser, private _element = element, private _by = by, private _$ = $, private _$$ = $$, private _expectedConditions = ExpectedConditions, private _error = error) {
    }

    public async click(locator: string, type = Type.CSS, cssText: string = null) {
        try {
            const loc: WebElement = await this.findElement(locator, type, cssText);
            await loc.click;
        } catch (e) {
           console.log(e);
        }
    }

    public async waitForAngularEnabled(value: boolean) {
        return this._browser.waitForAngularEnabled(value);
    }

    public async deleteAllCookies() {
        return await this._browser.manage().deleteAllCookies();
    }

    public async getCapabilities(capability: string) {
        return await this._browser.getCapabilities().then((cap) => {
            cap.get(capability);
          });
    }

    public async isDisplayed(locator: string, type = Type.CSS, cssText: string = null): Promise<boolean> {
        try {
            const loc: WebElement = await this.findElement(locator, type, cssText);
            return loc.isDisplayed();
        } catch (e) {
            console.log(e);
        }
    }

    public async isEnabled(locator: string, type = Type.CSS, cssText: string = null): Promise<boolean> {
        try {
            const loc: WebElement = await this.findElement(locator, type, cssText);
            return loc.isEnabled();
        } catch (e) {
            console.log(e);
        }
    }

    public async navigateTo(url: string) {
        return await this._browser.get(url);
    }

    public async getPageTitle(): Promise<string> {
        return await this._browser.getTitle();
    }

    public async getElementText(locator: string, type = Type.CSS, cssText: string = null): Promise<string> {
        try {
            const loc: WebElement = await this.findElement(locator, type, cssText);
            return loc.getText();
        } catch (e) {
            console.log(e);
        }
    }

    public async enterText(locator: string, text: string, type = Type.CSS, cssText: string = null) {
        try {
        const loc: WebElement = await this.findElement(locator, type, cssText);
        await loc.sendKeys(text);
        } catch (e) {
            console.log(e);
        }
    }

    public async getAttribute(locator: string, attribute: string, type = Type.CSS, cssText: string = null): Promise<string> {
        try {
            const loc: WebElement = await this.findElement(locator, type, cssText);
            return loc.getAttribute(attribute);
        } catch (e) {
            console.log(e);
        }
    }

    public async findElements(parentElement: string, type: Type, CssText: string = null): Promise<WebElement[]> {
        const loc = this._element.all;
        const visibility = this._expectedConditions.visibilityOf;
        const wait = this._browser.wait;
        switch (type) {
            case Type.BINDING : {
                const elements = loc(this._by.binding(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.EXACT_BINDING : {
                const elements = loc(this._by.exactBinding(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.MODEL: {
                const elements = loc(this._by.model(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.BUTTON_TEXT : {
                const elements = loc(this._by.buttonText(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.PARTIAL_BUTTON_TEXT : {
                const elements = loc(this._by.partialButtonText(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.REPEATER : {
                const elements = loc(this._by.repeater(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.EXACT_REPEATER : {
                const elements = loc(this._by.exactRepeater(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.CSS_CONTAINING_TEXT : {
                const elements = loc(this._by.cssContainingText(parentElement, CssText));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.OPTIONS : {
                const elements = loc(this._by.options(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.DEEP_CSS : {
                const elements = loc(this._by.deepCss(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.CLASS_NAME : {
                const elements = loc(this._by.className(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.CSS : {
                const elements: ElementArrayFinder = loc(this._$$(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.ID : {
                const elements = loc(this._by.id(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.LINK_TEXT : {
                const elements = loc(this._by.linkText(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.JS : {
                const elements = loc(this._by.js(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.NAME : {
                const elements = loc(this._by.name(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.PARTIAL_LINK_TEXT : {
                const elements = loc(this._by.partialLinkText(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.TAG_NAME : {
                const elements = loc(this._by.tagName(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            case Type.XPATH : {
                const elements = loc(this._by.xpath(parentElement));
                const condition = visibility(elements.last());
                await wait(condition, this._elementTimeOut);
                return elements.getWebElements();
            }
            default:
                throw new Error('Unable to find element with given ' + parentElement );
       }
    }

    private async findElement(locator: string, type: Type , CssText: string = null): Promise<ElementFinder> {
        const visibility = this._expectedConditions.visibilityOf;
        const wait = await this._browser.wait;
       switch (type) {
            case Type.BINDING : {
                const el = this._element(this._by.binding(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.EXACT_BINDING : {
                const el = this._element(this._by.exactBinding(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.MODEL: {
                const el = this._element(this._by.model(locator));
                wait(visibility(el), this._elementTimeOut).then(function () {
                    return el;
                });
                break;
            }
            case Type.BUTTON_TEXT : {
                const el = this._element(this._by.buttonText(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.PARTIAL_BUTTON_TEXT : {
                const el = this._element(this._by.partialButtonText(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.REPEATER : {
                const el = this._element(this._by.repeater(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.EXACT_REPEATER : {
                const el = this._element(this._by.exactRepeater(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.CSS_CONTAINING_TEXT : {
                const el = this._element(this._by.cssContainingText(locator, CssText));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.OPTIONS : {
                const el = this._element(this._by.options(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.DEEP_CSS : {
                const el = this._element(this._by.deepCss(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.CLASS_NAME : {
                const el = this._element(this._by.className(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.CSS : {
                const el = this._element(this._by.$(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.ID : {
                const el = this._element(this._by.id(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.LINK_TEXT : {
                const el = this._element(this._by.linkText(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.JS : {
                const el = this._element(this._by.js(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.NAME : {
                const el = this._element(this._by.name(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.PARTIAL_LINK_TEXT : {
                const el = this._element(this._by.partialLinkText(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            case Type.XPATH : {
                const el = this._element(this._by.xpath(locator));
                wait(visibility(el), this._elementTimeOut).then(function() {
                    return el;
                });
                break;
            }
            default:
                throw new Error('Unable to find element with given ' + locator );
       }
    }
}

这是我的规格文件:

import 'jasminewd2';
import { LoginPage } from '../Pages/login.pageObjects';
import { HomePage } from '../Pages/home.pageObjects';
import { CommonPageHelper } from '../Common/common.helper';

  describe('Login Page Elements View Tests', () => {
    beforeAll(() => {
      const _helper = new CommonPageHelper();
      const _loginPage = new LoginPage(_helper);
      _helper.navigateTo('/account/login');
      _helper.waitForAngularEnabled(false);

      it('should display page title', () => {
        expect(_loginPage.getLoginPageTitle()).toEqual('CashFlo | India\'s private working capital exchange');
      });

      it('should display cashflo logo', () => {
        expect(_loginPage.getCashfloLogoText()).toEqual('CashFlo');
      });

      it('should display hello text', () => {
        expect(_loginPage.getHellotext()).toEqual('Hello!');
      });

      it('should display welcome message', () => {
        expect(_loginPage.getWelcomeMessage()).toEqual('Welcome to CashFlo');
      });

      it('should display login page content', () => {
        expect(_loginPage.getLoginPageContent()).toContain('India\'s first private working capital exchange'  );
      });

      it('should display signin text', () => {
        expect(_loginPage.getSignUpText()).toEqual('Sign-in');
      });

      it('should display username text', () => {
        expect(_loginPage.getUsernameText()).toEqual('Username');
      });

      it('should display password text', () => {
        expect(_loginPage.getPasswordText()).toEqual('Password');
      });

      it('should disable login button with out credetials', () => {
        expect(_loginPage.IsLoginButtonEnabled()).toEqual(false);
      });
  });
});

describe('Buyer Account Login Test', () => {
  beforeEach(() => {
    const _helper = new CommonPageHelper();
    const _loginPage = new LoginPage(_helper);
    const _homePage = new HomePage(_helper);
    _helper.navigateTo('/account/login');
    _helper.waitForAngularEnabled(true);

    it('Using buyer credentials, it should navigate to home page after login', () => {
      _loginPage.enterUsernameText(BUYERUSERNAME);
      _loginPage.enterPasswordText(BUYERPASSWORD);
      _loginPage.clickOnSubmitButton();
      expect(_homePage.isBillDiscountingElementVisible).toEqual(true);
    });
  });
});

describe('Vendor Account Login Test', () => {
  beforeEach(() => {
    const _helper = new CommonPageHelper();
    const _loginPage = new LoginPage(_helper);
    const _homePage = new HomePage(_helper);
    _helper.navigateTo('/account/login');
    _helper.waitForAngularEnabled(true);
    _helper.deleteAllCookies();

    it('Using vendor credentials, it should navigate to bill discount page', () => {
      _loginPage.enterUsernameText(VENDORUSERNAME);
      _loginPage.enterPasswordText(VENDORPASSWORD);
      _loginPage.clickOnSubmitButton();
      expect(_homePage.isBillDiscountingElementVisible).toEqual(true);
    });
  });
});

describe('Invalid Username Login Credentials Test', () => {
  beforeEach(() => {
    const _helper = new CommonPageHelper();
    const _loginPage = new LoginPage(_helper);
    const _homePage = new HomePage(_helper);
    _helper.navigateTo('/account/login');
    _helper.waitForAngularEnabled(true);
    _helper.deleteAllCookies();

    it('Using invalid username, it should throw an error saying invalid user credentials', () => {
      _loginPage.enterUsernameText('ven@google.com');
      _loginPage.enterPasswordText(VENDORPASSWORD);
      _loginPage.clickOnSubmitButton();
      expect(_loginPage.getLoginErrorMessage()).toEqual('Username or Password Incorrect');
    });
  });
});

describe('Invalid Password Login Credentials Test', () => {
  beforeEach(() => {
    const _helper = new CommonPageHelper();
    const _loginPage = new LoginPage(_helper);
    const _homePage = new HomePage(_helper);
    _helper.navigateTo('/account/login');
    _helper.waitForAngularEnabled(true);
    _helper.deleteAllCookies();

    it('Using invalid password, it should throw an error saying invalid user credentials', () => {
      _loginPage.enterUsernameText(VENDORUSERNAME);
      _loginPage.enterPasswordText('1234');
      _loginPage.clickOnSubmitButton();
      expect(_loginPage.getLoginErrorMessage()).toEqual('Username or Password Incorrect');
    });
  });
});

1 个答案:

答案 0 :(得分:0)

问题出在您的spec文件中的config路径

  specs: [
    './e2e/Tests/login.spec.ts'
  ],

希望它对您有帮助