diff --git a/protractor-helpers/protractor-helpers-tests.ts b/protractor-helpers/protractor-helpers-tests.ts
new file mode 100644
index 000000000..b80c57c53
--- /dev/null
+++ b/protractor-helpers/protractor-helpers-tests.ts
@@ -0,0 +1,114 @@
+///
+
+import helpers = require('protractor-helpers');
+
+function testElementArrayFinder() {
+
+ var single1 : protractor.ElementFinder = $$('.foo').getByText('Hello');
+ var multiple : protractor.ElementArrayFinder = $$('.foo').$$data('Hello');
+
+}
+
+function testElementFinder () {
+ var single2 : protractor.ElementFinder = $('.foo').$data('Hello');
+}
+
+function testGlobals() {
+
+ var single : protractor.ElementFinder = $data('Hello');
+ var multiple : protractor.ElementArrayFinder = $$data('Hello');
+
+}
+
+function testHelpers() {
+
+ var q0 : webdriver.promise.IThenable = helpers.not($('.foo').isDisplayed());
+ // TODO - Check impl
+ var q1 : webdriver.promise.IThenable<{[key: string]:string}> = helpers.translate(["foo", "bar"]);
+ var q2 : webdriver.promise.IThenable<{[key: string]:string}> = helpers.translate(["foo", "bar"], {name: 'foo'});
+ var q3 : webdriver.promise.IThenable = helpers.translate("foo");
+ var q4 : webdriver.promise.IThenable = helpers.translate("foo", {name: 'foo'});
+
+ helpers.safeGet('https://foo/');
+
+ helpers.maximizeWindow(500, 500);
+ helpers.maximizeWindow(500);
+ helpers.maximizeWindow(undefined, 500);
+ helpers.maximizeWindow();
+
+ helpers.resetPosition();
+ helpers.moveToElement(".foo"); // TODO - ?
+
+ helpers.displayHover($('.foo'));
+
+ helpers.waitForElement($('.foo'));
+ helpers.waitForElement($('.foo'), 1000);
+ helpers.waitForElementToDisappear($('.foo'));;
+ helpers.waitForElementToDisappear($('.foo'), 1000);
+
+ helpers.selectOptionByText($('select'), "GB");
+ helpers.selectOptionByIndex($('select'), 1);
+
+ helpers.selectOption($$('select option').first());
+
+ var ff : boolean = helpers.isFirefox();
+ var ie : boolean = helpers.isIE();
+
+ var msg : string = helpers.createMessage("actual", "message", true);
+ var msg : string = helpers.createMessage($('.foo'), "message", true);
+ var msg : string = helpers.createMessage($$('.foo'), "message", true);
+
+ helpers.clearAndSetValue($('input'), 'Foo');
+
+ var hc : webdriver.promise.IThenable = helpers.hasClass($('.foo'), 'foo');
+
+ var hv : webdriver.promise.IThenable = helpers.hasValue($('input[type=text]'), 'foo');
+ var hv1 : webdriver.promise.IThenable = helpers.hasValue($('input[type=numeric]'), 12);
+ var hl : webdriver.promise.IThenable = helpers.hasLink($('div'), 'http://foo.com');
+ var disabled : webdriver.promise.IThenable = helpers.isDisabled($('foo'));
+ var checked : webdriver.promise.IThenable = helpers.isChecked($('foo'));
+
+ var q5 : webdriver.promise.IThenable = helpers.getFilteredConsoleErrors();
+
+}
+
+function testLocators() {
+
+ element(by.dataHook("foo"));
+ element(by.dataHook("foo", $('.parentfoo')));
+ element(by.dataHook("foo", undefined , ".foo"));
+ element(by.dataHook("foo", $('.parentfoo'), ".foo")); // TODO - This might not make much sense, but can technically be used in working code. Opinions welcome
+
+ element.all(by.dataHook("foo"));
+ element.all(by.dataHook("foo", $('parentfoo')));
+ element.all(by.dataHook("foo", undefined , ".foo"));
+ element.all(by.dataHook("foo", $('parentfoo'), ".foo")); // TODO - This might not make much sense, but can technically be used in working code. Opinions welcome
+
+}
+
+function testMatchers() {
+
+ var expectResult : boolean;
+ expectResult = expect($('.foo')).toBePresent();
+ expectResult = expect($('.foo')).toBeDisplayed();
+ expectResult = expect($$('.foo').count()).toHaveCountOf(1);
+ expectResult = expect($('.foo')).toHaveText("bla");
+ expectResult = expect($('.foo')).toMatchRegex(/bla/);
+ expectResult = expect($('.foo').getText()).toMatchMoney(123, "£");
+ expectResult = expect($('.foo').getText()).toMatchMoneyWithFraction(123.45, "£");
+ expectResult = expect($('input')).toHaveValue(12);
+ expectResult = expect($('input')).toHaveValue("bla");
+ expectResult = expect($('.foo')).toHaveClass("foo");
+ expectResult = expect($('.foo')).toHaveUrl('https://foo.com');
+ expectResult = expect($('.foo')).toBeDisabled();
+ expectResult = expect($('.foo')).toBeChecked();
+ expectResult = expect($('.foo')).toBeValid();
+ expectResult = expect($('.foo')).toBeInvalid();
+ expectResult = expect($('.foo')).toBeInvalidRequired();
+ expectResult = expect($('.foo')).toMatchTranslated("foo");
+ expectResult = expect($('.foo')).toMatchTranslated("foo", {foo: "bar"});
+ expectResult = expect($('.foo')).toMatchTranslated(["foo"]);
+ expectResult = expect($('.foo')).toMatchTranslated(["foo", "bla"], {foo: "bar"});
+
+}
+
diff --git a/protractor-helpers/protractor-helpers.d.ts b/protractor-helpers/protractor-helpers.d.ts
new file mode 100644
index 000000000..8d08f7fc9
--- /dev/null
+++ b/protractor-helpers/protractor-helpers.d.ts
@@ -0,0 +1,111 @@
+// Type definitions for protractor-helpers v1.0.0
+// Project: https://github.com/wix/protractor-helpers
+// Definitions by: John Cant
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+///
+///
+///
+
+// ElementArrayFinder
+
+declare module protractor {
+ interface ElementArrayFinder {
+ getByText(text: string) : protractor.ElementFinder;
+ $$data(hook: string) : protractor.ElementArrayFinder;
+ }
+
+ interface ElementFinder {
+ $data(hook: string) : protractor.ElementFinder;
+ }
+}
+
+// Globals
+
+declare function $data(hook: string) : protractor.ElementFinder;
+declare function $$data(hook: string) : protractor.ElementArrayFinder;
+
+
+// Locators
+
+// TODO - find out about result of querySelector and querySelector all.
+// Are they Locator s?
+declare module protractor {
+ interface IProtractorLocatorStrategy {
+ dataHook(hook: string, optParentElement?: protractor.ElementFinder, optRootSelector?: string) : webdriver.Locator;
+ dataHookAll(hook: string, optParentElement?: protractor.ElementFinder, optRootSelector?: string) : webdriver.Locator;
+ }
+}
+
+// Matchers
+// TODO - Typescript doesn't really help much here
+// we don't know what type is being tested.
+// Fixing this would require modifying the
+// jasmine d.ts.
+
+declare module jasmine {
+ interface Matchers {
+ toBePresent() : boolean;
+ toBeDisplayed() : boolean;
+ toHaveCountOf(expectedCount : number) : boolean;
+ toHaveText(expectedText : string) : boolean;
+ toMatchRegex(regex : RegExp) : boolean;
+ toMatchMoney(expectedValue : number, currencySymbol? : string) : boolean;
+ toMatchMoneyWithFraction(expectedValue : number, currencySymbol?: string) : boolean;
+ toHaveValue(actual: string | number) : boolean;
+ toHaveClass(className : string) : boolean;
+ toHaveUrl(url : string) : boolean;
+ toBeDisabled() : boolean;
+ toBeChecked() : boolean;
+ toBeValid() : boolean;
+ toBeInvalid() : boolean;
+ toBeInvalidRequired() : boolean;
+ // Copied definitions from angular-translate.
+ toMatchTranslated(translationId : string, interpolateParams? : any) : boolean;
+ toMatchTranslated(translationId : string[], interpolateParams? : any) : boolean;
+ }
+}
+
+
+declare module "protractor-helpers" {
+
+ function not(arg: webdriver.promise.IThenable) : webdriver.promise.IThenable;
+
+ // Copied definitions from angular-translate.
+ function translate(translationId: string, interpolateParams?: any): webdriver.promise.IThenable;
+ function translate(translationId: string[], interpolateParams?: any): webdriver.promise.IThenable<{ [key: string]: string }>;
+
+ function safeGet(url: string) : void;
+
+ function maximizeWindow(width?: number, height?: number) : void; // TODO
+ function resetPosition() : void;
+ function moveToElement(hook: string) : void;
+ function displayHover(element: protractor.ElementFinder) : void;
+
+ function waitForElement(element: protractor.ElementFinder, timeout?: number) : void;
+ function waitForElementToDisappear(element: protractor.ElementFinder, timeout?: number) : void;
+
+ function selectOptionByText(select: protractor.ElementFinder, text: string) : void;
+ function selectOptionByIndex(select: protractor.ElementFinder, index: number) : void;
+
+ function selectOption(option: protractor.ElementFinder) : void
+
+ function isFirefox() : boolean;
+ function isIE() : boolean;
+
+ function createMessage(actual : string, message : string, isNot : any) : string; // isNot : boolean too inflexible
+ function createMessage(actual : protractor.ElementFinder, message : string, isNot : any) : string; // isNot : boolean too inflexible
+ function createMessage(actual : protractor.ElementArrayFinder, message : string, isNot : any) : string; // isNot : boolean too inflexible
+
+ function clearAndSetValue(input : protractor.ElementFinder, value : string) : void; // TODO - sendKeys(value)
+
+ function hasClass(element: protractor.ElementFinder, className: string) : webdriver.promise.IThenable;
+ function hasValue(element: protractor.ElementFinder, expectedValue: string) : webdriver.promise.IThenable;
+ function hasValue(element: protractor.ElementFinder, expectedValue: number) : webdriver.promise.IThenable;
+ function hasLink(element: protractor.ElementFinder, url: string) : webdriver.promise.IThenable;
+ function isDisabled(element: protractor.ElementFinder) : webdriver.promise.IThenable;
+ function isChecked(element: protractor.ElementFinder) : webdriver.promise.IThenable;
+ function getFilteredConsoleErrors() : webdriver.promise.IThenable; // TODO - discuss handling in IE
+
+}
+