Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ end_of_line=lf
charset=utf-8
trim_trailing_whitespace=true
insert_final_newline=true

[*.js]
indent_style=space
indent_size=2
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,5 @@ node_modules
# codeceptjs
e2e/output

# cypress
cypress
# cypress
cypress
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
os: linux
dist: trusty
dist: xenial

language: node_js

Expand All @@ -10,6 +10,7 @@ python:
- "3.6"

addons:
# https://stackoverflow.com/questions/57903415/travis-ci-chrome-62-instead-of-77
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦

chrome: stable
firefox: "67.0"

Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ typeformEmbed.makeWidget(element, url, options)
| hideFooter | Hide typeform footer, that appears showing the progress bar and the navigation buttons. | `Boolean` | false |
| hideHeaders | Hide typeform header, that appears when you have a Question group, or a long question that you need to scroll through to answer, like a Multiple Choice block. | `Boolean` | false |
| onSubmit | Callback function that will be executed right after the typeform is successfully submitted. | `Function` | - |
| onReady | Callback function that will be executed once the typeform is ready. | `Function` | - |

#### Example:

Expand All @@ -73,6 +74,9 @@ typeformEmbed.makeWidget(element, url, options)
hideScrollbars: true,
onSubmit: function () {
console.log('Typeform successfully submitted')
},
onReady: function () {
console.log('Typeform is ready')
}
}
)
Expand All @@ -99,6 +103,10 @@ typeformEmbed.makePopup(url, options)
| hideHeaders | Hide typeform header, that appears when you have a Question group, or a long question that you need to scroll through to answer, like a Multiple Choice block. | `Boolean` | false |
| drawerWidth | Specify the width of the drawer (only applies if using `mode` `"drawer_left"` or `"drawer_right"`). | `Number` (pixels) | 800 |
| onSubmit | Callback function that will be executed right after the typeform is successfully submitted. | `Function` | - |
| onReady | Callback function that will be executed once the typeform is ready. |
`Function` | - |
| onClose | Callback function that will be executed once the typeform is closed. |
`Function` | - |

#### Example:

Expand All @@ -112,6 +120,12 @@ typeformEmbed.makePopup(url, options)
hideScrollbars: true,
onSubmit: function () {
console.log('Typeform successfully submitted')
},
onReady: function () {
console.log('Typeform is ready')
},
onClose: function () {
console.log('Typeform is closed')
}
}
)
Expand Down Expand Up @@ -140,15 +154,15 @@ Although we have no hard limit, we recommend having a height of at least 350px.
We use `position: fixed` to position our modal relative to its containing block established by the viewport. If one of the modal ancestors has a `transform`, `perspective`, or `filter` css property set to something other than `none` the positioning will be relative to it and probably not visible by the user.

## Tests
In order to run visual tests, it is need an applitools key.
- Add a `.env` file in your root, you can look at the `.env.example`
In order to run visual tests, you need an applitools key.
- Add a `.env` file in your root, you can look at the `.env.example`
- Add your api key `EYES_API_KEY=HERE_GOES_YOUR_KEY`
- (Optional) You can add the url, by default the url is `http://localhost:8080`
- Start the server `yarn start`
- Run the tests with `yarn test`
- - This command will run all the tests. That means **unit tests**, **integration tests** and **visual tests**

This is the list of all the test commands, if you want to run them one by one:
This is the list of all the test commands, if you want to run them one by one:
- `yarn test:unit` --> Runs unit tests
- `yarn test:functional` --> Runs cross browser functional tests with Cypress
- `yarn test:visual` --> Runs visual tests with CodeceptJs, WebDriver, and Applitools.
Expand Down
27 changes: 14 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,29 @@
"clean:lib": "rm -rf lib",
"start": "NODE_ENV=development webpack-dev-server -d --config webpack.config.dist.js",
"test": "yarn lint && yarn test:unit && yarn test:visual && yarn test:functional",
"lint": "eslint ./src --ext .js --ignore-path .eslintignore",
"test:unit": "jest",
"test:unit:watch": "jest --watch",
"test:unit:coverage": "jest --coverage",
"test:visual": "yarn test:visual:install && yarn test:visual:chrome && yarn test:visual:firefox && yarn test:visual:mobile",
"lint": "yarn eslint ./src --ext .js --ignore-path .eslintignore",
"test:unit": "yarn jest",
"test:unit:watch": "yarn jest --watch",
"test:unit:coverage": "yarn jest --coverage",
"test:visual": "yarn run test:visual:install && yarn run test:visual:chrome && yarn run test:visual:firefox && yarn run test:visual:mobile",
"test:visual:install": "yarn selenium-standalone install --silent",
"test:visual:chrome": "yarn codeceptjs --config codecept-visual.conf.js run --steps --grep @desktop",
"test:visual:firefox": "yarn codeceptjs --config codecept-visual.conf.js run --steps --profile firefox --grep @desktop",
"test:visual:mobile": "yarn codeceptjs --config codecept-visual.conf.js run --steps --grep @mobile",
"test:functional:debug": "yarn cypress open",
"test:functional": "yarn test:functional:chrome && yarn test:functional:firefox",
"test:functional": "yarn run test:functional:chrome && yarn run test:functional:firefox",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 👍

"test:functional:firefox": "yarn cypress run --browser firefox",
"test:functional:chrome": "yarn cypress run --browser chrome",
"prepublish": "yarn run lib",
"semantic-release": "semantic-release --branch release",
"travis-deploy-once": "travis-deploy-once --pro",
"semantic-release": "yarn semantic-release --branch release",
"travis-deploy-once": "yarn travis-deploy-once --pro",
"copy": "yarn run copy:assets && yarn run copy:helpcenter && yarn run copy:demo",
"copy:assets": "copyfiles -f assets/* dist",
"copy:helpcenter": "copyfiles -f helpcenter/* dist",
"copy:demo": "copyfiles -f demo/* dist",
"copy:assets": "yarn copyfiles -f assets/* dist",
"copy:helpcenter": "yarn copyfiles -f helpcenter/* dist",
"copy:demo": "yarn copyfiles -f demo/* dist",
"build": "yarn run dist && yarn run lib && yarn run copy",
"dist": "yarn run clean:dist && webpack --config webpack.config.dist.js",
"lib": "yarn run clean:lib && webpack --config webpack.config.lib.js"
"dist": "yarn run clean:dist && yarn webpack --config webpack.config.dist.js",
"lib": "yarn run clean:lib && yarn webpack --config webpack.config.lib.js"
},
"devDependencies": {
"@applitools/eyes-webdriverio": "^5.7.2",
Expand Down Expand Up @@ -72,6 +72,7 @@
"jsdom": "^11.6.2",
"react": "16.12.0",
"react-dom": "16.12.0",
"regenerator-runtime": "^0.13.5",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed for async tests because babel is not up to date.

"selenium-standalone": "^6.17.0",
"semantic-release": "^12.2.5",
"travis-deploy-once": "^4.3.3",
Expand Down
20 changes: 16 additions & 4 deletions src/core/make-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Popup, {
DEFAULT_AUTOCLOSE_TIMEOUT
} from './views/popup'
import MobileModal from './views/mobile-modal'
import { getPostMessageHandler } from './utils/get-post-message-handler'

const DEFAULT_DRAWER_WIDTH = 800

Expand All @@ -41,7 +42,8 @@ const queryStringKeys = {
disableTracking: 'disable-tracking'
}

const renderComponent = (url, domNode, options, onClose) => {
const renderComponent = (params, options) => {
const { url, domNode, close } = params
const {
autoClose,
buttonText,
Expand All @@ -59,7 +61,7 @@ const renderComponent = (url, domNode, options, onClose) => {
render(
<Popup
embedId={embedId}
onClose={onClose}
onClose={close}
options={options}
url={urlWithQueryString}
/>,
Expand All @@ -73,7 +75,7 @@ const renderComponent = (url, domNode, options, onClose) => {
buttonText={buttonText}
embedId={embedId}
isAutoCloseEnabled={isAutoCloseEnabled}
onClose={onClose}
onClose={close}
onSubmit={onSubmit}
open
url={urlWithQueryString}
Expand All @@ -84,6 +86,9 @@ const renderComponent = (url, domNode, options, onClose) => {
}

export default function makePopup (url, options) {
window.addEventListener('message', getPostMessageHandler('form-ready', options.onReady))
window.addEventListener('message', getPostMessageHandler('form-closed', options.onClose))

const embedId = randomString()

options = {
Expand All @@ -109,10 +114,17 @@ export default function makePopup (url, options) {
open (event) {
const { currentTarget } = event || {}
const currentUrl = currentTarget && currentTarget.href ? currentTarget.href : url
renderComponent(currentUrl, domNode, options, this.close)
const params = {
domNode,
url: currentUrl,
close: this.close
}

renderComponent(params, options)
},
close () {
window.postMessage({ type: 'form-closed', embedId }, '*')

unmountComponentAtNode(domNode)
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/core/make-popup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,27 @@ describe('makePopup', () => {
expect(component.type.name).toEqual('Popup')
expect(component.props.options).toEqual(expect.objectContaining(options))
})

it(`onReady is called during initialization`, async () => {
const options = { onReady: jest.fn() }

makePopup(URL, options)

window.postMessage({ type: 'form-ready' }, '*')
await new Promise((resolve) => setTimeout(resolve))
expect(options.onReady).toHaveBeenCalledTimes(1)
expect(options.onReady).toHaveBeenCalledWith()
})

it(`onClose is called when form closes`, async () => {
const options = { onClose: jest.fn() }

makePopup(URL, options)

window.postMessage({ type: 'form-closed' }, '*')
await new Promise((resolve) => setTimeout(resolve))

expect(options.onClose).toHaveBeenCalledTimes(1)
expect(options.onClose).toHaveBeenCalledWith()
})
})
3 changes: 3 additions & 0 deletions src/core/make-widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
isMobile
} from './utils/mobile-detection'
import Widget from './views/widget'
import { getPostMessageHandler } from './utils/get-post-message-handler'

const defaultOptions = {
mode: 'embed-widget',
Expand All @@ -32,6 +33,8 @@ const queryStringKeys = {
export default function makeWidget (element, url, options) {
options = { ...defaultOptions, ...options }

window.addEventListener('message', getPostMessageHandler('form-ready', options.onReady))

const enabledFullscreen = isMobile(navigator.userAgent)

let queryStrings = replaceExistingKeys(options, queryStringKeys)
Expand Down
12 changes: 12 additions & 0 deletions src/core/make-widget.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,16 @@ describe('makeWidget', () => {

expect(component.type.name).toEqual('Widget')
})

it(`onReady is called during initialization`, async () => {
const element = document.createElement('div')
const options = { onReady: jest.fn() }

makeWidget(element, URL, options)

window.postMessage({ type: 'form-ready' }, '*')
await new Promise((resolve) => setTimeout(resolve))
expect(options.onReady).toHaveBeenCalledTimes(1)
expect(options.onReady).toHaveBeenCalledWith()
})
})
11 changes: 11 additions & 0 deletions src/core/utils/get-post-message-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const getPostMessageHandler = (type, handler, options = {}) => (event) => {
try {
if (event.data.type !== type) { return }

if (options.includePayload) {
handler(event)
} else {
handler()
}
} catch (e) { }
}
3 changes: 2 additions & 1 deletion test/setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('regenerator-runtime/runtime')
const { JSDOM } = require('jsdom')

// This setup creates a fake DOM with JSDOM and set globally
Expand All @@ -8,5 +9,5 @@ const { window } = new JSDOM('<html><body></body></html')
global.window = window
global.document = window.document
global.navigator = {
userAgent: 'node.js',
userAgent: 'node.js'
}
26 changes: 4 additions & 22 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4965,12 +4965,7 @@ esprima@^3.1.3:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=

esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==

esprima@^4.0.1:
esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
Expand Down Expand Up @@ -7490,15 +7485,7 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=

js-yaml@3.13.1, js-yaml@^3.12.0, js-yaml@^3.9.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"

js-yaml@^3.13.1:
js-yaml@3.13.1, js-yaml@^3.12.0, js-yaml@^3.13.1, js-yaml@^3.9.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
Expand Down Expand Up @@ -8071,12 +8058,7 @@ lodash.zip@^4.2.0:
resolved "https://registry.yarnpkg.com/lodash.zip/-/lodash.zip-4.2.0.tgz#ec6662e4896408ed4ab6c542a3990b72cc080020"
integrity sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=

lodash@4.17.15, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==

lodash@^4.15.0, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15:
lodash@4.17.15, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
Expand Down Expand Up @@ -10286,7 +10268,7 @@ regenerator-runtime@^0.11.0:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==

regenerator-runtime@^0.13.4:
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5:
version "0.13.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
Expand Down