CVE-2015-10090: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability, which was classified as problematic, has been found in Landing Pages Plugin up to 1.8.7 on WordPress. Affected by this issue is some unknown functionality. The manipulation leads to cross site scripting. The attack may be launched remotely. Upgrading to version 1.8.8 is able to address this issue. The name of the patch is c8e22c1340c11fedfb0a0a67ea690421bdb62b94. It is recommended to upgrade the affected component. The identifier of this vulnerability is VDB-222320.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2023-03-06T00:15Z
Repository: https://github.com/wp-plugins/landing-pages
Language: PHP
Files changed: classes/class.extend.php, classes/class.statistics.php, css/admin-landing-page-list.css, landing-pages.php, modules/module.ab-testing.php, modules/module.install.php, phpunit.xml.dist, readme.txt, shared/assets/css/admin/global-inbound-admin.css, shared/shortcodes/inbound-shortcodes.php, templates/simple-two-column/assets/css/style.css, tests/build/php.conf, tests/build/php.load, tests/build/scratchpad.sh, tests/build/travis-ci-apache, tests/codeception/_bootstrap.php, tests/codeception/_data/dump.sql, tests/codeception/_support/AcceptanceHelper.php, tests/codeception/_support/FunctionalHelper.php, tests/codeception/_support/UnitHelper.php, tests/codeception/acceptance.suite.yml, tests/codeception/acceptance/AcceptanceTester.php, tests/codeception/acceptance/LoginCept.php, tests/codeception/acceptance/StatisticsCept.php, tests/codeception/acceptance/WelcomeCept.php, tests/codeception/acceptance/_bootstrap.php, tests/codeception/functional.suite.yml, tests/codeception/functional/FunctionalTester.php, tests/codeception/functional/_bootstrap.php, tests/codeception/unit.suite.yml, tests/codeception/unit/UnitTester.php, tests/codeception/unit/_bootstrap.php, tests/phantomjs/server.js, tests/phantomjs/server.php, tests/phantomjs/server.sh, tests/phpunit/bootstrap.php, tests/phpunit/test.activations.php, tests/phpunit/test.statistics.php
Commit date: 2015-06-16 00:05:19 +0000
Commit message: Security patch for XSS

git-svn-id: https://plugins.svn.wordpress.org/landing-pages/trunk@1181513 b8457f37-d9ea-0310-8a92-e5e31aec5664

Diff: diff --git a/classes/class.extend.php b/classes/class.extend.php
new file mode 100644
index 0000000..410de9c
--- /dev/null
+++ b/classes/class.extend.php
@@ -0,0 +1,343 @@
+<?php
+
+
+class Landing_Pages_Load_Extensions {
+	
+	/**
+	*  Initializes Landing_Pages_Load_Extensions
+	*/
+	public function __construct() {
+		
+		/* Load core landing page config.php files */
+		self::load_core_template_configurations();
+		
+		/* Load uploaded landing page config.php files */
+		self::load_uploaded_template_configurations();
+		
+		/* load hooks & filters  */
+		self::load_hooks();
+	}
+
+	/**
+	*  Loads hooks and filiters
+	*/
+	public static function load_hooks() {
+		
+		/* Adds core metabox settings to extension data array */
+		add_filter( 'lp_extension_data' , array( __CLASS__ , 'add_core_setting_data' ) , 1 , 1);
+		
+		/* Modifies legacy template data key names for old, un-updated legacy templates */
+		add_filter( 'lp_extension_data', array( __CLASS__ , 'add_legacy_data_support') , 10 , 1 );
+		
+		/* Add license key inputs to all uploaded templates */
+		add_filter( 'lp_define_global_settings' , array( __CLASS__ , 'prepare_license_keys' ), 99, 1);
+	}
+	
+	/**
+	*  Adds core metaboxes setting data using lp_extension_data filter
+	*/
+	public static function add_core_setting_data( $data ) {
+		
+		if ( !is_admin() ) {
+			return;
+		}
+		
+		$data[ 'lp' ]['settings'] = 	array(
+			array(
+				'id'  => 'selected-template',
+				'label' => __( 'Select Template' , 'landing-pages'),
+				'description' =>  __( "This option provides a placeholder for the selected template data." , 'landing-pages'),
+				'type'  => 'radio', // this is not honored. Template selection setting is handled uniquely by core.
+				'default'  => 'default',
+				'options' => null // this is not honored. Template selection setting is handled uniquely by core.
+			),
+			array(
+				'id'  => 'main-headline',
+				'label' => __('Set Main Headline' , 'landing-pages'),
+				'description' => __( "Set Main Headline" , 'landing-pages'),
+				'type'  => 'text', // this is not honored. Main Headline Input setting is handled uniquely by core.
+				'default'  => '',
+				'options' => null
+			),
+		);
+		
+		return $data;
+	}
+	
+	/**
+	*  Looks for occurances of 'options' in template & extension data arrays and replaces key with 'settings'
+	*/
+	public static function add_legacy_data_support( $data ) {
+		if ( !is_admin() ) {
+			return;
+		}
+		
+		foreach ($data as $parent_key => $subarray)
+		{
+			if (is_array($subarray))
+			{
+				foreach ($subarray as $k=>$subsubarray)
+				{
+					/* change 'options' key to 'settings' */
+					if ($k=='options')
+						$data[$parent_key]['settings'] = $subsubarray;
+
+					if ($k=='category')
+						$data[$parent_key]['info']['category'] = $subsubarray;
+
+					if ($k=='version')
+						$data[$parent_key]['info']['version'] = $subsubarray;
+
+					if ($k=='label')
+						$data[$parent_key]['info']['label'] = $subsubarray;
+
+					if ($k=='description')
+						$data[$parent_key]['info']['description'] = $subsubarray;
+				}
+			}
+		}
+
+		return $data;
+	}
+	
+	/**
+	*  Adds licensing & automatic updates to uploaded templates
+	*  
+	*  @param ARRAY $global_settings contains all global setting data
+	*  
+	*  @retuns ARRAY $global_settings contains modified global setting data
+	*/
+	public static function prepare_license_keys( $global_settings ) {
+		
+		if ( !is_admin() ) {
+			return;
+		}
+		
+		$lp_data = self::get_extended_data();
+
+		$global_settings['lp-license-keys']['settings'][] = 	array(
+				'id'  => 'template-license-keys-header',
+				'description' => __( "Head to http://www.inboundnow.com/ to retrieve your license key for this template." , 'landing-pages') ,
+				'type'  => 'header',
+				'default' => '<h3 class="lp_global_settings_header">' . __('Template Licensing' , 'landing-pages') .'</h3>'
+		);
+
+		/* get master license key */
+		$inboundnow_master_key = get_option('inboundnow_master_license_key' , '');
+
+		/* Loop through all setting data and add licensing for uploaded templates only */
+		foreach ($lp_data as $key=>$data)
+		{
+
+			$array_core_templates = array('simple-solid-lite','countdown-lander','default','demo','dropcap','half-and-half','simple-two-column','super-slick','svtle','tubelar','rsvp-envelope', 'three-column-lander');
+
+			if ($key == 'lp' || substr($key,0,4) == 'ext-' ) {
+				continue;
+			}
+			
+			if (isset($data['info']['data_type']) && $data['info']['data_type']=='metabox') {
+				continue;
+			}
+			
+			if (in_array($key,$array_core_templates)) {
+				continue;
+			}
+
+			$template_name = $lp_data[$key]['info']['label'];
+			$global_settings['lp-license-keys']['settings'][$key] = 	array(
+				'id'  => $key,
+				'label' => $template_name,
+				'slug' => $key,
+				'description' => __( "Head to http://www.inboundnow.com/ to retrieve your license key for this template." , 'landing-pages') ,
+				'type'  => 'license-key'
+			);
+		}
+
+		return $global_settings;
+	}
+	
+	/**
+	* Loads core template config.php files
+	*
+	* @returns ARRAY contains template setting data
+	*/
+	public static function load_core_template_configurations() {
+		
+		if ( !is_admin() ) {
+			return;
+		}
+		
+		$template_ids = self::get_core_template_ids();
+
+		//Now load all config.php files with their custom meta data
+		if (count($template_ids)>0)
+		{
+			foreach ($template_ids as $name)
+			{
+				if ($name != ".svn" && $name != ".git"){
+				include_once( LANDINGPAGES_PATH . "/templates/$name/config.php");
+				}
+			}
+		}
+		
+		
+		/* Store all template config files in global */
+		$GLOBALS['lp_data'] = $lp_data;
+		
+		return $lp_data;
+	}
+	
+	/**
+	* Loads uploaded template config.php files
+	*
+	*/
+	public static function load_uploaded_template_configurations() {
+		global $lp_data;
+		
+		$template_ids = self::get_uploaded_template_ids();
+
+		/* loop through template ids and include their config file */
+		foreach ($template_ids as $name)
+		{
+			$match = FALSE;
+			if (strpos($name, 'tmp') !== FALSE || strpos($name, 'template-generator') !== FALSE) {
+				$match = TRUE;
+			}
+			if ($name != ".svn" && $name != ".git" && $name != 'template-generator' && $match === FALSE){
+				if (file_exists( LANDINGPAGES_UPLOADS_PATH . "$name/config.php")) {
+					include_once( LANDINGPAGES_UPLOADS_PATH . "$name/config.php");					
+				}
+			}
+		}
+		
+		
+		return $lp_data;		
+
+	}
+	
+	/**
+	* Gets array of uploaded template paths
+	*
+	* @returns ARRAY $template_ids array of uploaded template ids
+	*/
+	public static function get_uploaded_template_ids()
+	{
+		$template_ids = array();
+
+		if (!is_dir( LANDINGPAGES_UPLOADS_PATH )) {
+			wp_mkdir_p( LANDINGPAGES_UPLOADS_PATH );
+		}
+
+		$results = scandir( LANDINGPAGES_UPLOADS_PATH );
+
+		foreach ($results as $name) {
+			if ($name === '.' or $name === '..' or $name === '__MACOSX') continue;
+
+			if (is_dir( LANDINGPAGES_UPLOADS_PATH . '/' . $name)) {
+				$template_ids[] = $name;
+			}
+		}
+
+		return $template_ids;
+	}
+	
+	/**
+	* Gets array of uploaded template paths
+	*
+	* @returns ARRAY $template_ids array of uploaded template ids
+	*/
+	public static function get_core_template_ids()
+	{
+		$template_ids = array();
+		
+		$template_path = LANDINGPAGES_PATH."/templates/" ;
+		$results = scandir($template_path);
+
+		//scan through templates directory and pull in name paths
+		foreach ($results as $name) {
+			if ($name === '.' or $name === '..' or $name === '__MACOSX') continue;
+
+			if (is_dir($template_path . '/' . $name)) {
+				$template_ids[] = $name;
+			}
+		}
+
+		return $template_ids;
+	}
+	
+	/**
+	*  Get's array of template categories from loaded templates
+	*  
+	*  @returns ARRAY $template_cats array if template categories
+	*/	
+	public static function get_template_categories()
+	{
+		$template_settings = self::get_extended_data();	
+		
+		foreach ($template_settings as $key=>$val)
+		{
+			if ( $key=='lp' || substr($key,0,4)=='ext-' || isset($val['info']['data_type']) && $val['info']['data_type']=='metabox' ) {
+				continue;
+			}
+			
+			/* account for legacy data models */
+			if (isset($val['category'])) {
+				$cats = $val['category'];
+			} else	{
+				if (isset($val['info']['category'])) {
+					$cats = $val['info']['category'];
+				}
+			}
+
+			$cats = explode(',',$cats);
+
+			foreach ($cats as $cat_value)
+			{
+				$cat_value = trim($cat_value);
+				$name = str_replace(array('-','_'),' ',$cat_value);
+				$name = ucwords($name);
+
+				if (!isset($template_cats[$cat_value]))
+				{
+					$template_cats[$cat_value]['count'] = 1;
+				}
+				else
+				{
+					$template_cats[$cat_value]['count']++;
+				}
+
+				$template_cats[$cat_value]['value'] = $cat_value;
+				$template_cats[$cat_value]['label'] = "$name";
+			}
+		}
+
+		return $template_cats;
+	}
+	
+	/**
+	 *  Get's template and extension setting data
+	 *  
+	 *  @retuns ARRAY of template & extension data
+	 */
+	public static function get_extended_data() {
+		global $lp_data;
+		
+		$lp_data = apply_filters( 'lp_extension_data' , $lp_data);
+		
+		return $lp_data;
+	}
+	
+
+}
+
+new Landing_Pages_Load_Extensions;
+
+/* Get data array of template settings */
+function lp_get_extension_data() {
+	return Landing_Pages_Load_Extensions::get_extended_data();	
+}
+
+
+
+
+
diff --git a/classes/class.statistics.php b/classes/class.statistics.php
index 1d2d505..62da4c3 100644
--- a/classes/class.statistics.php
+++ b/classes/class.statistics.php
@@ -23,14 +23,21 @@ class Landing_Pages_Statistics {
      * @param INT $landing_page_id id of landing page
      * @param INT $vid id of specific variation
      *
      * @returns ARRAY of variation data
      */
-    public static function get_variations( $landing_page_id	, $vid = null ) {
+    public static function get_variations( $landing_page_id ) {
+        if (!$landing_page_id) {
+            return array();
+        }
 
         $variations = (self::$variations) ? self::$variations :  get_post_meta(  $landing_page_id , 'lp-ab-variations' , true );
-        $variations = explode( ',' , $variations );
+
+        if (!is_array($variations)) {
+            $variations = explode( ',' , $variations );
+        }
+
         $variations = array_filter( $variations , 'is_numeric' );
 
         return ( $variations ? $variations : array() );
     }
 
diff --git a/codecept.phar b/codecept.phar
new file mode 100644
index 0000000..a7c21f6
Binary files /dev/null and b/codecept.phar differ
diff --git a/css/admin-landing-page-list.css b/css/admin-landing-page-list.css
index 71d1896..4f524c7 100644
--- a/css/admin-landing-page-list.css
+++ b/css/admin-landing-page-list.css
@@ -17,82 +17,89 @@
 }
 
 #cr {
     width: 120px;
 }
+
 #cb {
-	width: 20px;
+    width: 20px;
 }
+
 .clear_stats {
-	color: red;
+    color: red;
 }
+
 .hover-description {
-	display: block;
-	color: grey;
-	font-size: 10px;
-	font-style: italic;
+    display: block;
+    color: grey;
+    font-size: 10px;
+    font-style: italic;
 }
+
 .lp-pop-description {
-	padding: 10px;
-padding-left: 4px;
-padding-top: 6px;
+    padding: 10px;
+    padding-left: 4px;
+    padding-top: 6px;
 }
+
 .lp-bottom-controls {
-	margin-left: 12px;
-color: red;
-font-size: 12px;
-margin-right: 8px;
+    margin-left: 12px;
+    color: red;
+    font-size: 12px;
+    margin-right: 8px;
 }
+
 .lp-delete-var-stats {
-	display: inline-block;
+    display: inline-block;
 }
+
 .lp-pop-description {
     display: block;
     max-width: 325px;
 }
 
 .lp-pop-close {
-	font-size: 11px;
-	position: absolute;
-	font-weight: 100;
-	right: 10px;
-	top: 3px;
+    font-size: 11px;
+    position: absolute;
+    font-weight: 100;
+    right: 10px;
+    top: 3px;
 }
 
 .winner-lp {
     background-color: #E2FFC9;
 }
 
-.lp-pop-edit a{
-    color:#fff;
+.lp-pop-edit a {
+    color: #fff;
 }
 
 .lp-extra {
     margin-left: 10px;
 }
 
 .lp-win {
-	color: green;
-	font-size: 14px;
-	font-weight: bold;
-	text-shadow: 1px 1px 1px rgba(255,255,255,0.5);
+    color: green;
+    font-size: 14px;
+    font-weight: bold;
+    text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5);
 }
 
 .lp-paused {
-	color: red;
-	font-size: 12px;
+    color: red;
+    font-size: 12px;
 }
 
 .lp-pop-controls {
     display: inline-block;
     margin-top: 8px;
 }
 
 .lp-pop-edit {
-	display: inline-block !important;
-	margin-right: 11px !important;
-	margin-left: 5px !important;
+    display: inline-block !important;
+    margin-right: 11px !important;
+    margin-left: 5px !important;
 }
 
 .qtip {
     background: #fff;
 }
@@ -100,262 +107,284 @@ margin-right: 8px;
 .qtip-tip {
     height: 10px !important;
 }
 
 .qtip-content, .lp-pop-description, .lp-pop-preview a {
-    color:#333;
+    color: #333;
 
 }
 
 .lp-pop-preview a, .lp-pop-edit a {
-   text-decoration: none;
+    text-decoration: none;
 }
 
-.qtip-titlebar
-{
-	position: relative;
-	padding: 0px;
+.qtip-titlebar {
+    position: relative;
+    padding: 0px;
 }
 
-.qtip-jtools
-{
-	border: 2px solid rgba(172, 172, 172, 1);
+.qtip-jtools {
+    border: 2px solid rgba(172, 172, 172, 1);
 }
 
 .qtip-title {
-	position: relative;
-	margin: 0 0 5px;
-	padding: 12px 17px 14px 14px;
-	line-height: 19px;
-	font-size: 19px;
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
-	background: #8cc1e9;
-	background-image: -webkit-gradient(linear,left bottom,left top,from(#72a7cf),to(#8cc1e9));
-	background-image: -webkit-linear-gradient(bottom,#72a7cf,#8cc1e9);
-	background-image: -moz-linear-gradient(bottom,#72a7cf,#8cc1e9);
-	background-image: -o-linear-gradient(bottom,#72a7cf,#8cc1e9);
-	background-image: linear-gradient(to top,#72a7cf,#8cc1e9);
+    position: relative;
+    margin: 0 0 5px;
+    padding: 12px 17px 14px 14px;
+    line-height: 19px;
+    font-size: 19px;
+    color: #fff;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+    background: #8cc1e9;
+    background-image: -webkit-gradient(linear, left bottom, left top, from(#72a7cf), to(#8cc1e9));
+    background-image: -webkit-linear-gradient(bottom, #72a7cf, #8cc1e9);
+    background-image: -moz-linear-gradient(bottom, #72a7cf, #8cc1e9);
+    background-image: -o-linear-gradient(bottom, #72a7cf, #8cc1e9);
+    background-image: linear-gradient(to top, #72a7cf, #8cc1e9);
 }
+
 .stats li {
     border-bottom: 1px solid #EBEBEA;
-	padding: 6px 20px;
-	margin: 0;
-	font-size: 13px;
-	vertical-align: top;
-	padding-left: 5px;
-	padding-right: 5px;
+    padding: 6px 20px;
+    margin: 0;
+    font-size: 13px;
+    vertical-align: top;
+    padding-left: 5px;
+    padding-right: 5px;
 }
 
-.stats li:hover
-{
-	background:#e0e0e0;
+.stats li:hover {
+    background: #e0e0e0;
 }
 
 .wp-list-table td.stats .show-stats, .show-stats, .variation-winner-is {
     display: none;
 }
 
 .wp-list-table td.stats .show-stats {
     margin-top: 10px;
-	padding-top: 0px;
-	margin-left: 4px;
-	position: absolute;
+    padding-top: 0px;
+    margin-left: 4px;
+    position: absolute;
 }
 
 td.stats.column-stats {
-	border: 1px solid #EBEBEA;
+    border: 1px solid #EBEBEA;
 
 }
 
 .wp-list-table td.stats {
     padding-left: 0px;
-	padding-right: 0px;
+    padding-right: 0px;
 }
 
-.lp-current-winner{
-  background-color: rgb(226, 255, 201);
+.lp-current-winner {
+    background-color: rgb(226, 255, 201);
 }
 
 #impressions span, #cr span, #actions span {
-	text-align: center;
-	float: none;
+    text-align: center;
+    float: none;
 }
 
 .lp-varation-stat-ul {
     min-width: 270px;
 }
 
 .status-0 {
     background-color: #F9DBDB !important;
-	font-weight: normal;
-	color: rgb(117, 117, 117) !important;
+    font-weight: normal;
+    color: rgb(117, 117, 117) !important;
 }
 
-.wp-list-table td.impressions, .wp-list-table td.actions, .wp-list-table td.cr{
+.wp-list-table td.impressions, .wp-list-table td.actions, .wp-list-table td.cr {
     font-size: 18px;
     color: #000;
-	margin: 0;
-	text-align: center;
-	padding-top: 15px;
-	border-right: 1px solid #EBEBEA;
+    margin: 0;
+    text-align: center;
+    padding-top: 15px;
+    border-right: 1px solid #EBEBEA;
 }
 
 .wp-list-table td.cr {
 }
 
 .row-title {
-	font-size: 15px!important;
-	margin-top: 2px !important;
-	display: inline-block;
+    font-size: 15px !important;
+    margin-top: 2px !important;
+    display: inline-block;
 }
 
 .wp-list-table td.actions {
 }
-.post-state .states{
-							font-size:10px;
-							padding:3px 8px 3px 8px;
-							-moz-border-radius:2px;
-							-webkit-border-radius:2px;
-							border-radius:2px;
-							}
-					.post-state .password{background:#000;color:#fff;}
-					.post-state .pending{background:#83CF21 !important;color:#fff;}
-					.post-state .private{background:#E0A21B;color:#fff;}
-					.post-state .draft{background:#006699;color:#fff;}
+
+.post-state .states {
+    font-size: 10px;
+    padding: 3px 8px 3px 8px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+    border-radius: 2px;
+}
+
+.post-state .password {
+    background: #000;
+    color: #fff;
+}
+
+.post-state .pending {
+    background: #83CF21 !important;
+    color: #fff;
+}
+
+.post-state .private {
+    background: #E0A21B;
+    color: #fff;
+}
+
+.post-state .draft {
+    background: #006699;
+    color: #fff;
+}
+
 #hide-stats, .show-stats-top {
-	color: #21759b;
-	font-size: 9px;
-	padding-left: 10px;
+    color: #21759b;
+    font-size: 9px;
+    padding-left: 10px;
 }
 
-.stats li:last-child{
+.stats li:last-child {
     border-bottom: none;
 }
 
 .no-stats-yet {
-	padding-left: 7px;
-padding-top: 6px;
-color: #777;
-font-size: 11px;
-display: none;
+    padding-left: 7px;
+    padding-top: 6px;
+    color: #777;
+    font-size: 11px;
+    display: none;
 }
 
 .widefat td.stats {
     border-top: none;
     padding-top: 0px;
 }
 
 .widefat td.stats ul {
-	font-size: 12px;
-	border-top: none;
-	width: 	100%;
-	border-bottom: none;
-	margin-bottom: -2px;
-	padding-bottom: 0px;
-	display: inline-block;
-	margin-top: 0px;
+    font-size: 12px;
+    border-top: none;
+    width: 100%;
+    border-bottom: none;
+    margin-bottom: -2px;
+    padding-bottom: 0px;
+    display: inline-block;
+    margin-top: 0px;
 }
+
 .lp-numbers {
-	font-size: 13px;
-	min-width: 199px;
-	display: inline-block;
+    font-size: 13px;
+    min-width: 199px;
+    display: inline-block;
 }
+
 .introjs-showElement .row-actions {
-visibility: visible;}
+    visibility: visible;
+}
+
 .lp-impress-num {
-	display: inline-block;
-	text-align: center;
-	min-width: 30px;
-	padding-right: 5px;
-	padding-left: 5px;
+    display: inline-block;
+    text-align: center;
+    min-width: 30px;
+    padding-right: 5px;
+    padding-left: 5px;
 }
 
 .lp-no-stats {
-	display: inline-block;
-	padding-left: 10px;
-	color: #ccc;
+    display: inline-block;
+    padding-left: 10px;
+    color: #ccc;
 }
 
 .lp-impress-num, .lp-con-num, .cr-number {
-	font-weight: bold;
-	font-size: 19px;
+    font-weight: bold;
+    font-size: 19px;
 }
 
 .visit-text {
-	display: inline-block;
-	min-width: 60px;
+    display: inline-block;
+    min-width: 60px;
 }
 
 .lp-con-num {
-	display: inline-block;
-	padding-left: 4px;
-	padding-right: 4px;
+    display: inline-block;
+    padding-left: 4px;
+    padding-right: 4px;
 }
 
 .lp-letter, .cr-number, .cr-number.cr-empty-0 {
-	display: inline-block;
-
-	font-size: 20px;
-	min-width: 16px;
-	min-height: 20px;
-	border-radius: 3px;
-	background: #f3f3f3;
-	background-image: -webkit-gradient(linear,left top,left bottom,from(#fefefe),to(#f4f4f4));
-	background-image: -webkit-linear-gradient(top,#fefefe,#f4f4f4);
-	background-image: -moz-linear-gradient(top,#fefefe,#f4f4f4);
-	background-image: -o-linear-gradient(top,#fefefe,#f4f4f4);
-	background-image: linear-gradient(to bottom,#fefefe,#f4f4f4);
-	border-color: #bbb;
-	color: #333;
-	text-shadow: 0 1px 0 #fff;
-	font-family: sans-serif;
-	cursor: pointer;
-	border-width: 1px;
-	border-style: solid;
-	padding: 1px;
-	padding-left: 4px;
-	text-align: center;
-	padding-right: 5px;
-	padding-top: 6px;
-	margin-right: 5px;
+    display: inline-block;
+
+    font-size: 20px;
+    min-width: 16px;
+    min-height: 20px;
+    border-radius: 3px;
+    background: #f3f3f3;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#f4f4f4));
+    background-image: -webkit-linear-gradient(top, #fefefe, #f4f4f4);
+    background-image: -moz-linear-gradient(top, #fefefe, #f4f4f4);
+    background-image: -o-linear-gradient(top, #fefefe, #f4f4f4);
+    background-image: linear-gradient(to bottom, #fefefe, #f4f4f4);
+    border-color: #bbb;
+    color: #333;
+    text-shadow: 0 1px 0 #fff;
+    font-family: sans-serif;
+    cursor: pointer;
+    border-width: 1px;
+    border-style: solid;
+    padding: 1px;
+    padding-left: 4px;
+    text-align: center;
+    padding-right: 5px;
+    padding-top: 6px;
+    margin-right: 5px;
 }
 
 .cr-number {
     margin-left: 5px;
     padding-left: 5px;
     background-color: #21759b;
-	background-image: -webkit-gradient(linear,left top,left bottom,from(#2a95c5),to(#21759b));
-	background-image: -webkit-linear-gradient(top,#2a95c5,#21759b);
-	background-image: -moz-linear-gradient(top,#2a95c5,#21759b);
-	background-image: -ms-linear-gradient(top,#2a95c5,#21759b);
-	background-image: -o-linear-gradient(top,#2a95c5,#21759b);
-	background-image: linear-gradient(to bottom,#2a95c5,#21759b);
-	border-color: #21759b;
-	border-bottom-color: #1e6a8d;
-	-webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
-	box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
-	color: #fff;
-	text-shadow: 0 1px 0 rgba(0,0,0,0.1);
-	font-weight: normal;
-	margin-right: 0px !important;
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2a95c5), to(#21759b));
+    background-image: -webkit-linear-gradient(top, #2a95c5, #21759b);
+    background-image: -moz-linear-gradient(top, #2a95c5, #21759b);
+    background-image: -ms-linear-gradient(top, #2a95c5, #21759b);
+    background-image: -o-linear-gradient(top, #2a95c5, #21759b);
+    background-image: linear-gradient(to bottom, #2a95c5, #21759b);
+    border-color: #21759b;
+    border-bottom-color: #1e6a8d;
+    -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5);
+    box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5);
+    color: #fff;
+    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
+    font-weight: normal;
+    margin-right: 0px !important;
 }
+
 .cr-number.cr-empty-0 {
-	font-weight: normal !important;
-color: #ccc;
-box-shadow: none;
--webkit-box-shadow: none;
+    font-weight: normal !important;
+    color: #ccc;
+    box-shadow: none;
+    -webkit-box-shadow: none;
 }
- a.cr-number:hover {
+
+a.cr-number:hover {
     background-color: #278ab7;
-	background-image: -webkit-gradient(linear,left top,left bottom,from(#2e9fd2),to(#21759b));
-	background-image: -webkit-linear-gradient(top,#2e9fd2,#21759b);
-	background-image: -moz-linear-gradient(top,#2e9fd2,#21759b);
-	background-image: -ms-linear-gradient(top,#2e9fd2,#21759b);
-	background-image: -o-linear-gradient(top,#2e9fd2,#21759b);
-	background-image: linear-gradient(to bottom,#2e9fd2,#21759b);
-	border-color: #1b607f;
-	-webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
-	box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
-	color: #fff;
-	text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
-}
\ No newline at end of file
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#2e9fd2), to(#21759b));
+    background-image: -webkit-linear-gradient(top, #2e9fd2, #21759b);
+    background-image: -moz-linear-gradient(top, #2e9fd2, #21759b);
+    background-image: -ms-linear-gradient(top, #2e9fd2, #21759b);
+    background-image: -o-linear-gradient(top, #2e9fd2, #21759b);
+    background-image: linear-gradient(to bottom, #2e9fd2, #21759b);
+    border-color: #1b607f;
+    -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6);
+    box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6);
+    color: #fff;
+    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
+}
diff --git a/landing-pages.php b/landing-pages.php
index 879e84e..f00fda2 100644
--- a/landing-pages.php
+++ b/landing-pages.php
@@ -1,11 +1,11 @@
 <?php
 /*
 Plugin Name: Landing Pages
 Plugin URI: http://www.inboundnow.com/landing-pages/
 Description: The first true all-in-one Landing Page solution for WordPress, including ongoing conversion metrics, a/b split testing, unlimited design options and so much more!
-Version: 1.8.6
+Version: 1.8.8
 Author: Inbound Now
 Author URI: http://www.inboundnow.com/
 Text Domain: landing-pages
 Domain Path: lang
 */
@@ -36,11 +36,11 @@ if (!class_exists('Inbound_Landing_Pages_Plugin')) {
 		* Setup plugin constants
 		*
 		*/
 		private static function load_constants() {
 
-			define('LANDINGPAGES_CURRENT_VERSION', '1.8.6' );
+			define('LANDINGPAGES_CURRENT_VERSION', '1.8.8' );
 			define('LANDINGPAGES_URLPATH', plugins_url( '/' , __FILE__ ) );
 			define('LANDINGPAGES_PATH', WP_PLUGIN_DIR.'/'.plugin_basename( dirname(__FILE__) ).'/' );
 			define('LANDINGPAGES_PLUGIN_SLUG', plugin_basename( dirname(__FILE__) ) );
 			define('LANDINGPAGES_FILE', __FILE__ );
 			define('LANDINGPAGES_STORE_URL', 'http://www.inboundnow.com/' );
diff --git a/modules/module.ab-testing.php b/modules/module.ab-testing.php
index 4896aee..b0e1206 100644
--- a/modules/module.ab-testing.php
+++ b/modules/module.ab-testing.php
@@ -1,8 +1,9 @@
 <?php
 
 /* ADMIN ONLY AB TESTING FUNCTIONS */
+
 if (is_admin()) {
 	include_once(LANDINGPAGES_PATH.'modules/module.ab-testing.metaboxes.php');
 
 	/**
 	 * [lp_ab_unset_variation description]
@@ -48,11 +49,11 @@ if (is_admin()) {
 	add_action('init','lp_ab_testing_admin_init');
 	function lp_ab_testing_admin_init($hook)
 	{
 		if (!is_admin()||!isset($_GET['post'])||!is_numeric($_GET['post'])) {
 			return;
-		}
+        }
 
 		$post = get_post($_GET['post']);
 
 		if (isset($post)&&($post->post_type=='landing-page'&&(isset($_GET['action'])&&$_GET['action']=='edit')))
 		{
@@ -60,12 +61,11 @@ if (is_admin()) {
 			$current_variation_id = lp_ab_testing_get_current_variation_id();
 			//echo $current_variation_id;
 			$variations = get_post_meta($post->ID,'lp-ab-variations', true);
 
 			//remove landing page's main save_post action
-			if ($current_variation_id>0)
-			{
+			if ($current_variation_id>0) {
 				remove_action('save_post','lp_save_meta',10);
 			}
 
 			//check for delete command
 			if (isset($_GET['ab-action'])&&$_GET['ab-action']=='delete-variation')
@@ -98,866 +98,866 @@ if (is_admin()) {
 					SELECT `meta_key`, `meta_value`
 					FROM $wpdb->postmeta
 					WHERE `post_id` = ".$post__ID."
 				");
 
-				foreach($wpdb->last_result as $k => $v){
-					$data[$v->meta_key] =   $v->meta_value;
-				};
-				//echo $len;exit;
-				foreach ($data as $key=>$value)
-				{
-					if (substr($key,-$len)==$suffix)
-					{
-						delete_post_meta($_GET['post'], $key, $value);
-					}
-				}
-
-				$_GET['lp-variation-id'] = $current_variation_id;
-			}
-
-			//check for pause command
-			if (isset($_GET['ab-action'])&&$_GET['ab-action']=='pause-variation')
-			{
-				if ($_GET['lp-variation-id']==0)
-				{
-					update_post_meta( $post->ID , 'lp_ab_variation_status' , '0' );
-				}
-				else
-				{
-					update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '0');
-				}
-			}
-
-			//check for pause command
-			if (isset($_GET['ab-action'])&&$_GET['ab-action']=='play-variation')
-			{
-				if ($_GET['lp-variation-id']==0)
-				{
-					update_post_meta( $post->ID , 'lp_ab_variation_status' , '1' );
-				}
-				else
-				{
-					update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '1');
-				}
-			}
-
-			//return;
-
-			(isset($_GET['new-variation'])&&$_GET['new-variation']==1) ? $new_variation = 1 : $new_variation = 0;
-
-			$content_area = lp_content_area($post,null,true);
-
-			//prepare for new variation creation - use A as default content if not being cloned
-			if (($new_variation==1&&!isset($_GET['clone']))||isset($_GET['clone'])&&$_GET['clone']==0)
-			{
-				$content_area = get_post_field('post_content', $_GET['post']);
-				$content_area = wpautop($content_area);
-			}
-			else if ($new_variation==1&&isset($_GET['clone']))
-			{
-				$content_area = get_post_field('content-'.$_GET['clone'], $_GET['post']);
-				$content_area = wpautop($content_area);
-			}
-
-			//if new variation and cloning then programatically prepare the next variation id
-			if($new_variation==1&&isset($_GET['clone']))
-			{
-				$array_variations = explode(',',$variations);
-				sort($array_variations,SORT_NUMERIC);
-
-				$lid = end($array_variations);
-				$current_variation_id = $lid+1;
-
-				$_SESSION['lp_ab_test_open_variation'] = $current_variation_id;
-			}
-			//echo $current_variation_id;exit;
-			//enqueue and localize scripts
-			wp_enqueue_style('lp-ab-testing-admin-css', LANDINGPAGES_URLPATH . 'css/admin-ab-testing.css');
-			wp_enqueue_script('lp-ab-testing-admin-js', LANDINGPAGES_URLPATH . 'js/admin/admin.post-edit-ab-testing.js', array( 'jquery' ));
-			wp_localize_script( 'lp-ab-testing-admin-js', 'variation', array( 'pid' => $_GET['post'], 'vid' => $current_variation_id  , 'new_variation' => $new_variation  , 'variations'=> $variations  , 'content_area' => $content_area  ));
-
-		}
-
-	}
-
-	/* force visual editor to open in text mode */
-
-	function lp_ab_testing_force_default_editor() {
-		//allowed: tinymce, html, test
-		return 'html';
-	}
-
-	add_filter('lp_edit_main_headline','lp_ab_testing_admin_prepare_headline');
-	function lp_ab_testing_admin_prepare_headline($main_headline)
-	{
-
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if (isset($_REQUEST['post']))
-		{
-			$post_id = $_REQUEST['post'];
-		}
-		else if (isset($_REQUEST['lp_id']))
-		{
-			$post_id = $_REQUEST['lp_id'];
-		}
-
-		//return "hello";
-
-		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
-		{
-			$main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
-		}
-		else if (isset($_GET['clone'])&&$_GET['clone']>0)
-		{
-			$main_headline = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
-		}
-
-		if (!$main_headline&&isset($_REQUEST['post']))
-		{
-			get_post_meta($_REQUEST['post'],'lp-main-headline', true);
-		}
-
-		return $main_headline;
-	}
-
-	//disable this because it will populate all wp_editor isntances rather than targeted instances
-	//add_filter('the_editor_content', 'lp_ab_testing_the_editor_content');
-	function lp_ab_testing_the_editor_content($content) {
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if (isset($_REQUEST['post']))
-		{
-			$post_id = $_REQUEST['post'];
-		}
-		else if (isset($_REQUEST['lp_id']))
-		{
-			$post_id = $_REQUEST['lp_id'];
-		}
-
-		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
-		{
-			$content = get_post_field('content-'.$current_variation_id, $post_id);
-		}
-		else if (isset($_GET['clone']))
-		{
-			$content = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
-		}
-
-		return $content;
-	}
-
-
-	add_filter('lp_edit_variation_notes','lp_ab_testing_admin_prepare_notes');
-	function lp_ab_testing_admin_prepare_notes($variation_notes)
-	{
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if (isset($_REQUEST['post']))
-		{
-			$post_id = $_REQUEST['post'];
-		}
-		else if (isset($_REQUEST['lp_id']))
-		{
-			$post_id = $_REQUEST['lp_id'];
-		}
-
-		//return "hello";
-
-		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
-		{
-			$variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$current_variation_id, true);
-		}
-		else if (isset($_GET['clone'])&&$_GET['clone']>0)
-		{
-			$variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$_GET['clone'], true);
-		}
-
-		if (!$variation_notes&&isset($_REQUEST['post']))
-		{
-			get_post_meta($_REQUEST['post'],'lp-variation-notes', true);
-		}
-
-		return $variation_notes;
-	}
-
-	add_filter('lp_selected_template_id','lp_ab_testing_prepare_id');//prepare name id for hidden selected template input
-	add_filter('lp_display_headline_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
-	add_filter('lp_display_notes_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
-	function lp_ab_testing_prepare_id($id)
-	{
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		//check if variation clone is initiated
-		if (isset($_GET['new_meta_key']))
-			$current_variation_id = $_GET['new_meta_key'];
-
-		if ($current_variation_id>0)
-		{
-			$id = $id.'-'.$current_variation_id;
-		}
-
-		return $id;
-	}
-
-	//prepare id for wp_editor in template customizer
-	add_filter('lp_wp_editor_id','lp_ab_testing_prepare_wysiwyg_editor_id');
-	function lp_ab_testing_prepare_wysiwyg_editor_id($id)
-	{
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-		//echo $current_variation_id;exit;
-		if ($current_variation_id>0)
-		{
-			switch ($id) {
-				case "wp_content":
-					$id = 'content-'.$current_variation_id;
-					break;
-				case "lp-conversion-area":
-					$id = 'landing-page-myeditor-'.$current_variation_id;
-					break;
-				default:
-					$id = $id.'-'.$current_variation_id;
-			}
-
-		}
-
-		return $id;
-	}
-
-
-	add_filter('lp_show_metabox','lp_ab_testing_admin_prepare_meta_ids', 5, 2);
-	function lp_ab_testing_admin_prepare_meta_ids($lp_custom_fields, $main_key)
-	{
-		if (isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
-		{
-			return $lp_custom_fields;
-		}
-
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if (isset($_GET['clone'])) {
-			$current_variation_id = $_GET['clone'];
-		}
-
-		if ($current_variation_id>0)
-		{
-			$post_id = $_GET['post'];
-			foreach ($lp_custom_fields as $key=>$field)
-			{
-				$default = get_post_meta($post_id, $field['id'], true);
-
-				$id = $field['id'];
-				$field['id'] = $id.'-'.$current_variation_id ;
-
-				if ($default) {
-					$field['default'] = $default;
-				}
-
-				$lp_custom_fields[$key] = $field;
-			}
-			return $lp_custom_fields;
-		}
-
-		//print_r($lp_custom_fields);exit;
-		return $lp_custom_fields;
-	}
-
-	add_filter('lp_variation_selected_template','lp_ab_testing_lp_variation_selected_template', 10, 2);
-	function lp_ab_testing_lp_variation_selected_template($selected_template, $post)
-	{
-		if (isset($_GET['new-variation']))
-			return $selected_template;
-
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if ($current_variation_id>0)
-		{
-			$selected_template = get_post_meta( $post->ID , 'lp-selected-template-'.$current_variation_id , true);
-		}
-
-		//print_r($lp_custom_fields);exit;
-		return $selected_template;
-	}
-
-	//add filter to modify thumbnail preview
-	add_filter('lp_live_screenshot_url', 'lp_ab_testing_prepare_screenshot');
-	function lp_ab_testing_prepare_screenshot($link)
-	{
-		$variation_id = lp_ab_testing_get_current_variation_id();
-		$link = $link."?lp-variation-id=".$variation_id;
-		return $link;
-	}
-
-
-
-	add_filter("post_type_link", "lp_ab_append_variation_id_to_adminbar_link", 10,2);
-	function lp_ab_append_variation_id_to_adminbar_link($link, $post)
-	{
-		if( $post->post_type == 'landing-page' )
-		{
-			$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-			if ($current_variation_id>0)
-				$link = $link."?lp-variation-id=".$current_variation_id;
-		}
-
-		return $link;
-	}
-
-	if(!defined('AUTOSAVE_INTERVAL')) {
-    define('AUTOSAVE_INTERVAL', 86400);
-	}
+                foreach($wpdb->last_result as $k => $v){
+                    $data[$v->meta_key] =   $v->meta_value;
+                };
+                //echo $len;exit;
+                foreach ($data as $key=>$value)
+                {
+                    if (substr($key,-$len)==$suffix)
+                    {
+                        delete_post_meta($post__ID, $key, $value);
+                    }
+                }
+
+                $_GET['lp-variation-id'] = $current_variation_id;
+            }
+
+            //check for pause command
+            if (isset($_GET['ab-action'])&&$_GET['ab-action']=='pause-variation')
+            {
+                if ($_GET['lp-variation-id']==0)
+                {
+                    update_post_meta( $post->ID , 'lp_ab_variation_status' , '0' );
+                }
+                else
+                {
+                    update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '0');
+                }
+            }
+
+            //check for pause command
+            if (isset($_GET['ab-action'])&&$_GET['ab-action']=='play-variation')
+            {
+                if ($_GET['lp-variation-id']==0)
+                {
+                    update_post_meta( $post->ID , 'lp_ab_variation_status' , '1' );
+                }
+                else
+                {
+                    update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '1');
+                }
+            }
+
+            //return;
+
+            (isset($_GET['new-variation'])&&$_GET['new-variation']==1) ? $new_variation = 1 : $new_variation = 0;
+
+            $content_area = lp_content_area($post,null,true);
+
+            //prepare for new variation creation - use A as default content if not being cloned
+            if (($new_variation==1&&!isset($_GET['clone']))||isset($_GET['clone'])&&$_GET['clone']==0)
+            {
+                $content_area = get_post_field('post_content', $_GET['post']);
+                $content_area = wpautop($content_area);
+            }
+            else if ($new_variation==1&&isset($_GET['clone']))
+            {
+                $content_area = get_post_field('content-'.$_GET['clone'], $_GET['post']);
+                $content_area = wpautop($content_area);
+            }
+
+            //if new variation and cloning then programatically prepare the next variation id
+            if($new_variation==1&&isset($_GET['clone']))
+            {
+                $array_variations = explode(',',$variations);
+                sort($array_variations,SORT_NUMERIC);
+
+                $lid = end($array_variations);
+                $current_variation_id = $lid+1;
+
+                $_SESSION['lp_ab_test_open_variation'] = $current_variation_id;
+            }
+            //echo $current_variation_id;exit;
+            //enqueue and localize scripts
+            wp_enqueue_style('lp-ab-testing-admin-css', LANDINGPAGES_URLPATH . 'css/admin-ab-testing.css');
+            wp_enqueue_script('lp-ab-testing-admin-js', LANDINGPAGES_URLPATH . 'js/admin/admin.post-edit-ab-testing.js', array( 'jquery' ));
+            wp_localize_script( 'lp-ab-testing-admin-js', 'variation', array( 'pid' => $_GET['post'], 'vid' => $current_variation_id  , 'new_variation' => $new_variation  , 'variations'=> $variations  , 'content_area' => $content_area  ));
+
+        }
+
+    }
+
+    /* force visual editor to open in text mode */
+
+    function lp_ab_testing_force_default_editor() {
+        //allowed: tinymce, html, test
+        return 'html';
+    }
+
+    add_filter('lp_edit_main_headline','lp_ab_testing_admin_prepare_headline');
+    function lp_ab_testing_admin_prepare_headline($main_headline)
+    {
+
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if (isset($_REQUEST['post']))
+        {
+            $post_id = $_REQUEST['post'];
+        }
+        else if (isset($_REQUEST['lp_id']))
+        {
+            $post_id = $_REQUEST['lp_id'];
+        }
+
+        //return "hello";
+
+        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
+        {
+            $main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
+        }
+        else if (isset($_GET['clone'])&&$_GET['clone']>0)
+        {
+            $main_headline = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
+        }
+
+        if (!$main_headline&&isset($_REQUEST['post']))
+        {
+            get_post_meta($_REQUEST['post'],'lp-main-headline', true);
+        }
+
+        return $main_headline;
+    }
+
+    //disable this because it will populate all wp_editor isntances rather than targeted instances
+    //add_filter('the_editor_content', 'lp_ab_testing_the_editor_content');
+    function lp_ab_testing_the_editor_content($content) {
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if (isset($_REQUEST['post']))
+        {
+            $post_id = $_REQUEST['post'];
+        }
+        else if (isset($_REQUEST['lp_id']))
+        {
+            $post_id = $_REQUEST['lp_id'];
+        }
+
+        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
+        {
+            $content = get_post_field('content-'.$current_variation_id, $post_id);
+        }
+        else if (isset($_GET['clone']))
+        {
+            $content = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
+        }
+
+        return $content;
+    }
+
+
+    add_filter('lp_edit_variation_notes','lp_ab_testing_admin_prepare_notes');
+    function lp_ab_testing_admin_prepare_notes($variation_notes)
+    {
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if (isset($_REQUEST['post']))
+        {
+            $post_id = $_REQUEST['post'];
+        }
+        else if (isset($_REQUEST['lp_id']))
+        {
+            $post_id = $_REQUEST['lp_id'];
+        }
+
+        //return "hello";
+
+        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
+        {
+            $variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$current_variation_id, true);
+        }
+        else if (isset($_GET['clone'])&&$_GET['clone']>0)
+        {
+            $variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$_GET['clone'], true);
+        }
+
+        if (!$variation_notes&&isset($_REQUEST['post']))
+        {
+            get_post_meta($_REQUEST['post'],'lp-variation-notes', true);
+        }
+
+        return $variation_notes;
+    }
+
+    add_filter('lp_selected_template_id','lp_ab_testing_prepare_id');//prepare name id for hidden selected template input
+    add_filter('lp_display_headline_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
+    add_filter('lp_display_notes_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
+    function lp_ab_testing_prepare_id($id)
+    {
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        //check if variation clone is initiated
+        if (isset($_GET['new_meta_key']))
+            $current_variation_id = $_GET['new_meta_key'];
+
+        if ($current_variation_id>0)
+        {
+            $id = $id.'-'.$current_variation_id;
+        }
+
+        return $id;
+    }
+
+    //prepare id for wp_editor in template customizer
+    add_filter('lp_wp_editor_id','lp_ab_testing_prepare_wysiwyg_editor_id');
+    function lp_ab_testing_prepare_wysiwyg_editor_id($id)
+    {
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+        //echo $current_variation_id;exit;
+        if ($current_variation_id>0)
+        {
+            switch ($id) {
+                case "wp_content":
+                    $id = 'content-'.$current_variation_id;
+                    break;
+                case "lp-conversion-area":
+                    $id = 'landing-page-myeditor-'.$current_variation_id;
+                    break;
+                default:
+                    $id = $id.'-'.$current_variation_id;
+            }
+
+        }
+
+        return $id;
+    }
+
+
+    add_filter('lp_show_metabox','lp_ab_testing_admin_prepare_meta_ids', 5, 2);
+    function lp_ab_testing_admin_prepare_meta_ids($lp_custom_fields, $main_key)
+    {
+        if (isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
+        {
+            return $lp_custom_fields;
+        }
+
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if (isset($_GET['clone'])) {
+            $current_variation_id = $_GET['clone'];
+        }
+
+        if ($current_variation_id>0)
+        {
+            $post_id = $_GET['post'];
+            foreach ($lp_custom_fields as $key=>$field)
+            {
+                $default = get_post_meta($post_id, $field['id'], true);
+
+                $id = $field['id'];
+                $field['id'] = $id.'-'.$current_variation_id ;
+
+                if ($default) {
+                    $field['default'] = $default;
+                }
+
+                $lp_custom_fields[$key] = $field;
+            }
+            return $lp_custom_fields;
+        }
+
+        //print_r($lp_custom_fields);exit;
+        return $lp_custom_fields;
+    }
+
+    add_filter('lp_variation_selected_template','lp_ab_testing_lp_variation_selected_template', 10, 2);
+    function lp_ab_testing_lp_variation_selected_template($selected_template, $post)
+    {
+        if (isset($_GET['new-variation']))
+            return $selected_template;
+
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if ($current_variation_id>0)
+        {
+            $selected_template = get_post_meta( $post->ID , 'lp-selected-template-'.$current_variation_id , true);
+        }
+
+        //print_r($lp_custom_fields);exit;
+        return $selected_template;
+    }
+
+    //add filter to modify thumbnail preview
+    add_filter('lp_live_screenshot_url', 'lp_ab_testing_prepare_screenshot');
+    function lp_ab_testing_prepare_screenshot($link)
+    {
+        $variation_id = lp_ab_testing_get_current_variation_id();
+        $link = $link."?lp-variation-id=".$variation_id;
+        return $link;
+    }
+
+
+
+    add_filter("post_type_link", "lp_ab_append_variation_id_to_adminbar_link", 10,2);
+    function lp_ab_append_variation_id_to_adminbar_link($link, $post)
+    {
+        if( $post->post_type == 'landing-page' )
+        {
+            $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+            if ($current_variation_id>0)
+                $link = $link."?lp-variation-id=".$current_variation_id;
+        }
+
+        return $link;
+    }
+
+    if(!defined('AUTOSAVE_INTERVAL')) {
+        define('AUTOSAVE_INTERVAL', 86400);
+    }
 
     add_filter('wp_insert_post_data','lp_ab_testing_wp_insert_post_data',10,2);
-	function lp_ab_testing_wp_insert_post_data($data,$postarr)
-	{
-
-		//exit;
-		//$variation_id = lp_ab_testing_get_current_variation_id();
-		//echo $variation_id;exit;
-		if (isset($postarr['lp-variation-id'])&&$postarr['lp-variation-id']>0)
-		{
-			$postarr = array();
-			$data = array();
-
-			remove_action('save_post','lp_save_meta',10);
-			remove_action('save_post','lp_ab_testing_save_post',10);
-
-			$postID = $_POST['post_ID'];
-			if($parent_id = wp_is_post_revision($_POST['post_ID']))
-			{
-				$postID = $parent_id;
-			}
-
-			lp_ab_testing_save_post($postID);
-
-		}
-		else
-		{
-			//echo "here";exit;
-			//$this_data = json_encode($data);
-			//mail('hudson.atwell@gmail.com','test2',$this_data);
-		}
-
-		if (count($data)>1)
-			return $data;
-	}
-
-	add_action('save_post','lp_ab_testing_save_post');
-	function lp_ab_testing_save_post($postID)
-	{
-		global $post;
-
-		$var_final = (isset($_POST['lp-variation-id'])) ? $_POST['lp-variation-id'] : '0';
-		if (  isset($_POST['post_type']) && $_POST['post_type']=='landing-page')
-		{
-			if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||$_POST['post_type']=='revision')
-			{
-				return;
-			}
-
-			if($parent_id = wp_is_post_revision($postID))
-			{
-				$postID = $parent_id;
-			}
-
-
-			$this_variation = $var_final;
-			//echo $this_variation;
-			//print_r($_POST);exit;
-
-			//first add to varation list if not present.
-			$variations = get_post_meta($postID,'lp-ab-variations', true);
-			if ($variations)
-			{
-				$array_variations = explode(',',$variations);
-				if (!in_array($this_variation,$array_variations))
-				{
-					$array_variations[] = $this_variation;
-				}
-			}
-			else
-			{
-				if  ($this_variation>0)
-				{
-					$array_variations[] = 0;
-					$array_variations[] = $this_variation;
-				}
-				else
-				{
-					$array_variations[] = $this_variation;
-				}
-			}
-
-			//print_r($array_variations);exit;
-			//update_post_meta($postID,'lp-ab-variations', "");
-			update_post_meta($postID,'lp-ab-variations', implode(',',$array_variations));
-			//add_post_meta($postID, 'lp_ab_variation_status-'.$this_variation , 1);
-
-			//echo $this_variation;exit;
-			if ($this_variation==0)
-			{
-				return;
-			}
-			//echo $this_variation;exit;
-			//print_r($_POST);
-
-			//next alter all custom fields to store correct varation and create custom fields for special inputs
-			$ignore_list = array('post_status','post_type','tax_input','post_author','user_ID','post_ID','catslist','post_title','samplepermalinknonce',
-			'autosavenonce','action','autosave','mm','jj','aa','hh','mn','ss','_wp_http_referer','lp-variation-id','_wpnonce','originalaction','original_post_status',
-			'referredby','_wp_original_http_referer','meta-box-order-nonce','closedpostboxesnonce','hidden_post_status','hidden_post_password','hidden_post_visibility','visibility',
-			'post_password','hidden_mm','cur_mm','hidden_jj','cur_jj','hidden_aa','cur_aa','hidden_hh','cur_hh','hidden_mn','cur_mn','original_publish','save','newlanding_page_category','newlanding_page_category_parent',
-			'_ajax_nonce-add-landing_page_category','lp_lp_custom_fields_nonce','lp-selected-template','post_mime_type','ID','comment_status','ping_status');
-
-			//$special_list = array('content','post-content');
-			//print_r($_POST);exit;
-			//echo $this_variation;exit;
-			foreach ($_POST as $key=>$value)
-			{
-				//echo $key." : -{$this_variation} : $value<br>";
-				if (!in_array($key,$ignore_list)&&!strstr($key,'nonce'))
-				{
-					if ($key=='post_content')
-						$key = 'content';
-
-					if (!strstr($key,"-{$this_variation}"))
-					{
-						$new_array[$key.'-'.$this_variation] = $value;
-					}
-					else
-					{
-						//echo $key." : -{$this_variation}<br>";
-						$new_array[$key] = $value;
-					}
-				}
-				//echo $key." : -{$this_variation} : $value<br>";
-			}
-
-			//print_r($new_array);exit;
-
-			foreach($new_array as $key => $val)
-			{
-				$old = get_post_meta($postID, $key, true);
-				$new = $val;
-				//echo "$key  : $old v. $new <br>";
-				//if (isset($new) && $new != $old ) {
-					update_post_meta($postID, $key, $new);
-				//} elseif ('' == $new && $old) {
-					//delete_post_meta($postID, $key, $old);
-				//}
-			}
-
-		}
-	}
+    function lp_ab_testing_wp_insert_post_data($data,$postarr)
+    {
+
+        //exit;
+        //$variation_id = lp_ab_testing_get_current_variation_id();
+        //echo $variation_id;exit;
+        if (isset($postarr['lp-variation-id'])&&$postarr['lp-variation-id']>0)
+        {
+            $postarr = array();
+            $data = array();
+
+            remove_action('save_post','lp_save_meta',10);
+            remove_action('save_post','lp_ab_testing_save_post',10);
+
+            $postID = $_POST['post_ID'];
+            if($parent_id = wp_is_post_revision($_POST['post_ID']))
+            {
+                $postID = $parent_id;
+            }
+
+            lp_ab_testing_save_post($postID);
+
+        }
+        else
+        {
+            //echo "here";exit;
+            //$this_data = json_encode($data);
+            //mail('hudson.atwell@gmail.com','test2',$this_data);
+        }
+
+        if (count($data)>1)
+            return $data;
+    }
+
+    add_action('save_post','lp_ab_testing_save_post');
+    function lp_ab_testing_save_post($postID)
+    {
+        global $post;
+
+        $var_final = (isset($_POST['lp-variation-id'])) ? $_POST['lp-variation-id'] : '0';
+        if (  isset($_POST['post_type']) && $_POST['post_type']=='landing-page')
+        {
+            if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||$_POST['post_type']=='revision')
+            {
+                return;
+            }
+
+            if($parent_id = wp_is_post_revision($postID))
+            {
+                $postID = $parent_id;
+            }
+
+
+            $this_variation = $var_final;
+            //echo $this_variation;
+            //print_r($_POST);exit;
+
+            //first add to varation list if not present.
+            $variations = get_post_meta($postID,'lp-ab-variations', true);
+            if ($variations)
+            {
+                $array_variations = explode(',',$variations);
+                if (!in_array($this_variation,$array_variations))
+                {
+                    $array_variations[] = $this_variation;
+                }
+            }
+            else
+            {
+                if  ($this_variation>0)
+                {
+                    $array_variations[] = 0;
+                    $array_variations[] = $this_variation;
+                }
+                else
+                {
+                    $array_variations[] = $this_variation;
+                }
+            }
+
+            //print_r($array_variations);exit;
+            //update_post_meta($postID,'lp-ab-variations', "");
+            update_post_meta($postID,'lp-ab-variations', implode(',',$array_variations));
+            //add_post_meta($postID, 'lp_ab_variation_status-'.$this_variation , 1);
+
+            //echo $this_variation;exit;
+            if ($this_variation==0)
+            {
+                return;
+            }
+            //echo $this_variation;exit;
+            //print_r($_POST);
+
+            //next alter all custom fields to store correct varation and create custom fields for special inputs
+            $ignore_list = array('post_status','post_type','tax_input','post_author','user_ID','post_ID','catslist','post_title','samplepermalinknonce',
+                'autosavenonce','action','autosave','mm','jj','aa','hh','mn','ss','_wp_http_referer','lp-variation-id','_wpnonce','originalaction','original_post_status',
+                'referredby','_wp_original_http_referer','meta-box-order-nonce','closedpostboxesnonce','hidden_post_status','hidden_post_password','hidden_post_visibility','visibility',
+                'post_password','hidden_mm','cur_mm','hidden_jj','cur_jj','hidden_aa','cur_aa','hidden_hh','cur_hh','hidden_mn','cur_mn','original_publish','save','newlanding_page_category','newlanding_page_category_parent',
+                '_ajax_nonce-add-landing_page_category','lp_lp_custom_fields_nonce','lp-selected-template','post_mime_type','ID','comment_status','ping_status');
+
+            //$special_list = array('content','post-content');
+            //print_r($_POST);exit;
+            //echo $this_variation;exit;
+            foreach ($_POST as $key=>$value)
+            {
+                //echo $key." : -{$this_variation} : $value<br>";
+                if (!in_array($key,$ignore_list)&&!strstr($key,'nonce'))
+                {
+                    if ($key=='post_content')
+                        $key = 'content';
+
+                    if (!strstr($key,"-{$this_variation}"))
+                    {
+                        $new_array[$key.'-'.$this_variation] = $value;
+                    }
+                    else
+                    {
+                        //echo $key." : -{$this_variation}<br>";
+                        $new_array[$key] = $value;
+                    }
+                }
+                //echo $key." : -{$this_variation} : $value<br>";
+            }
+
+            //print_r($new_array);exit;
+
+            foreach($new_array as $key => $val)
+            {
+                $old = get_post_meta($postID, $key, true);
+                $new = $val;
+                //echo "$key  : $old v. $new <br>";
+                //if (isset($new) && $new != $old ) {
+                update_post_meta($postID, $key, $new);
+                //} elseif ('' == $new && $old) {
+                //delete_post_meta($postID, $key, $old);
+                //}
+            }
+
+        }
+    }
 
 }
 
 /* PERFORM FRONT-END ONLY ACTIONS */
 else
 {
 
-	//prepare customizer meta data for ab varations
-	add_filter('lp_get_value','lp_ab_testing_prepare_variation_meta', 1 , 4);
-	function lp_ab_testing_prepare_variation_meta($return, $post, $key, $id)
-	{
-		if (isset($_REQUEST['lp-variation-id'])||isset($_COOKIE['lp-variation-id']))
-		{
-			(isset($_REQUEST['lp-variation-id'])) ? $variation_id = $_REQUEST['lp-variation-id'] : $variation_id = $_COOKIE['lp-variation-id'];
-			if ($variation_id>0)
-					return do_shortcode(get_post_meta($post->ID, $key.'-'.$id. '-' .$variation_id , true));
-			else
-				return $return;
-		}
-		else
-		{
-			return $return;
-		}
-	}
-
-	//prepare customizer, admin, and preview links for variations
-	add_filter('lp_customizer_customizer_link', 'lp_ab_append_variation_id_to_link');
-	add_filter('lp_customizer_admin_bar_link', 'lp_ab_append_variation_id_to_link');
-	add_filter('lp_customizer_preview_link','lp_ab_append_variation_id_to_link');
-
-	function lp_ab_append_variation_id_to_link($link)
-	{
-
-		$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-		if ($current_variation_id>0)
-			$link = $link."&lp-variation-id=".$current_variation_id;
-
-		return $link;
-	}
+    //prepare customizer meta data for ab varations
+    add_filter('lp_get_value','lp_ab_testing_prepare_variation_meta', 1 , 4);
+    function lp_ab_testing_prepare_variation_meta($return, $post, $key, $id)
+    {
+        if (isset($_REQUEST['lp-variation-id'])||isset($_COOKIE['lp-variation-id']))
+        {
+            (isset($_REQUEST['lp-variation-id'])) ? $variation_id = $_REQUEST['lp-variation-id'] : $variation_id = $_COOKIE['lp-variation-id'];
+            if ($variation_id>0)
+                return do_shortcode(get_post_meta($post->ID, $key.'-'.$id. '-' .$variation_id , true));
+            else
+                return $return;
+        }
+        else
+        {
+            return $return;
+        }
+    }
+
+    //prepare customizer, admin, and preview links for variations
+    add_filter('lp_customizer_customizer_link', 'lp_ab_append_variation_id_to_link');
+    add_filter('lp_customizer_admin_bar_link', 'lp_ab_append_variation_id_to_link');
+    add_filter('lp_customizer_preview_link','lp_ab_append_variation_id_to_link');
+
+    function lp_ab_append_variation_id_to_link($link)
+    {
+
+        $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+        if ($current_variation_id>0)
+            $link = $link."&lp-variation-id=".$current_variation_id;
+
+        return $link;
+    }
 
 }
 
 /*PERFORM ACTIONS REQUIRED ON BOTH FRONT AND BACKEND */
 
 add_filter('lp_content_area','lp_ab_testing_alter_content_area_admin', 10, 2);
 function lp_ab_testing_alter_content_area_admin($content)
 {
-	global $post;
+    global $post;
 
-	$variation_id = lp_ab_testing_get_current_variation_id();
+    $variation_id = lp_ab_testing_get_current_variation_id();
 
-	if ($variation_id>0)
-	{
-		$content = get_post_meta($post->ID,'content-'.$variation_id, true);
-		if ( !is_admin() )
-		{
-			$content = wpautop($content);
-			$content = do_shortcode($content);
-		}
-	}
+    if ($variation_id>0)
+    {
+        $content = get_post_meta($post->ID,'content-'.$variation_id, true);
+        if ( !is_admin() )
+        {
+            $content = wpautop($content);
+            $content = do_shortcode($content);
+        }
+    }
 
-	return $content;
+    return $content;
 }
 
 /* RETURN LETTER FROM ARRAY KEY */
 function lp_ab_key_to_letter($key) {
     $alphabet = array( 'A', 'B', 'C', 'D', 'E',
-                       'F', 'G', 'H', 'I', 'J',
-                       'K', 'L', 'M', 'N', 'O',
-                       'P', 'Q', 'R', 'S', 'T',
-                       'U', 'V', 'W', 'X', 'Y',
-                       'Z'
-                       );
-
-	if (isset($alphabet[$key])) {
-		return $alphabet[$key];
-	}
+        'F', 'G', 'H', 'I', 'J',
+        'K', 'L', 'M', 'N', 'O',
+        'P', 'Q', 'R', 'S', 'T',
+        'U', 'V', 'W', 'X', 'Y',
+        'Z'
+    );
+
+    if (isset($alphabet[$key])) {
+        return $alphabet[$key];
+    }
 }
 
 /* GET CURRENT VARIATION ID */
 function lp_ab_testing_get_current_variation_id()
 {
-	if ( isset($_GET['ab-action']) &&is_admin())
-	{
-		return $_SESSION['lp_ab_test_open_variation'];
-	}
-
-	if (!isset($_SESSION['lp_ab_test_open_variation'])&&!isset($_REQUEST['lp-variation-id']))
-	{
-		$current_variation_id = 0;
-	}
-	//echo $_REQUEST['lp-variation-id'];
-	if (isset($_REQUEST['lp-variation-id']))
-	{
-		$_SESSION['lp_ab_test_open_variation'] = $_REQUEST['lp-variation-id'];
-		$current_variation_id = $_REQUEST['lp-variation-id'];
-		//echo "setting session $current_variation_id";
-	}
-
-	if (isset($_GET['message'])&&$_GET['message']==1&&isset( $_SESSION['lp_ab_test_open_variation'] ))
-	{
-		$current_variation_id = $_SESSION['lp_ab_test_open_variation'];
-
-		//echo "here:".$_SESSION['lp_ab_test_open_variation'];
-	}
-
-	if (isset($_GET['ab-action'])&&$_GET['ab-action']=='delete-variation')
-	{
-		$current_variation_id = 0;
-		$_SESSION['lp_ab_test_open_variation'] = 0;
-	}
-
-	if (!isset($current_variation_id))
-		$current_variation_id = 0 ;
-
-	return $current_variation_id;
+    if ( isset($_GET['ab-action']) &&is_admin())
+    {
+        return $_SESSION['lp_ab_test_open_variation'];
+    }
+
+    if (!isset($_SESSION['lp_ab_test_open_variation'])&&!isset($_REQUEST['lp-variation-id']))
+    {
+        $current_variation_id = 0;
+    }
+    //echo $_REQUEST['lp-variation-id'];
+    if (isset($_REQUEST['lp-variation-id']))
+    {
+        $_SESSION['lp_ab_test_open_variation'] = $_REQUEST['lp-variation-id'];
+        $current_variation_id = $_REQUEST['lp-variation-id'];
+        //echo "setting session $current_variation_id";
+    }
+
+    if (isset($_GET['message'])&&$_GET['message']==1&&isset( $_SESSION['lp_ab_test_open_variation'] ))
+    {
+        $current_variation_id = $_SESSION['lp_ab_test_open_variation'];
+
+        //echo "here:".$_SESSION['lp_ab_test_open_variation'];
+    }
+
+    if (isset($_GET['ab-action'])&&$_GET['ab-action']=='delete-variation')
+    {
+        $current_variation_id = 0;
+        $_SESSION['lp_ab_test_open_variation'] = 0;
+    }
+
+    if (!isset($current_variation_id))
+        $current_variation_id = 0 ;
+
+    return $current_variation_id;
 }
 
 //ready conversion area for displaying ab variations
 add_filter('lp_conversion_area_pre_standardize','lp_ab_testing_prepare_conversion_area' , 10 , 2 );
 function lp_ab_testing_prepare_conversion_area($content,$post=null)
 {
-	$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-	if (isset($post))
-	{
-		$post_id = $post->ID;
-	}
-	else if (isset($_REQUEST['post']))
-	{
-		$post_id = $_REQUEST['post'];
-	}
-	else if (isset($_REQUEST['lp_id']))
-	{
-		$post_id = $_REQUEST['lp_id'];
-	}
-
-
-	if ($current_variation_id>0)
-		$content = get_post_meta($post_id,'landing-page-myeditor-'.$current_variation_id, true);
-
-	return $content;
+    $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+    if (isset($post))
+    {
+        $post_id = $post->ID;
+    }
+    else if (isset($_REQUEST['post']))
+    {
+        $post_id = $_REQUEST['post'];
+    }
+    else if (isset($_REQUEST['lp_id']))
+    {
+        $post_id = $_REQUEST['lp_id'];
+    }
+
+
+    if ($current_variation_id>0)
+        $content = get_post_meta($post_id,'landing-page-myeditor-'.$current_variation_id, true);
+
+    return $content;
 }
 
 //ready conversion area for displaying ab variations
 add_filter('lp_conversion_area_position','lp_ab_testing_lp_conversion_area_position' , 10 , 2 );
 function lp_ab_testing_lp_conversion_area_position($position, $post = null, $key = 'default')
 {
 
-	$current_variation_id = lp_ab_testing_get_current_variation_id();
-
-	if (isset($post))
-	{
-		$post_id = $post->ID;
-	}
-	else if (isset($_REQUEST['post']))
-	{
-		$post_id = $_REQUEST['post'];
-	}
-	else if (isset($_REQUEST['lp_id']))
-	{
-		$post_id = $_REQUEST['lp_id'];
-	}
-
-	if ($current_variation_id>0)
-		$position = get_post_meta($post->ID, "{$key}-conversion-area-placement-".$current_variation_id, true);
-
-	return $position;
+    $current_variation_id = lp_ab_testing_get_current_variation_id();
+
+    if (isset($post))
+    {
+        $post_id = $post->ID;
+    }
+    else if (isset($_REQUEST['post']))
+    {
+        $post_id = $_REQUEST['post'];
+    }
+    else if (isset($_REQUEST['lp_id']))
+    {
+        $post_id = $_REQUEST['lp_id'];
+    }
+
+    if ($current_variation_id>0)
+        $position = get_post_meta($post->ID, "{$key}-conversion-area-placement-".$current_variation_id, true);
+
+    return $position;
 }
 
 
 add_filter('lp_main_headline','lp_ab_testing_prepare_headline', 10, 2);
 function lp_ab_testing_prepare_headline($main_headline, $post = null)
 {
 
-	$current_variation_id = lp_ab_testing_get_current_variation_id();
+    $current_variation_id = lp_ab_testing_get_current_variation_id();
 
-	if (isset($post))
-	{
-		$post_id = $post->ID;
-	}
-	else if (isset($_REQUEST['post']))
-	{
-		$post_id = $_REQUEST['post'];
-	}
-	else if (isset($_REQUEST['lp_id']))
-	{
-		$post_id = $_REQUEST['lp_id'];
-	}
-	else if (isset($_REQUEST['post_id']))
-	{
-		$post_id = $_REQUEST['post_id'];
-	}
+    if (isset($post))
+    {
+        $post_id = $post->ID;
+    }
+    else if (isset($_REQUEST['post']))
+    {
+        $post_id = $_REQUEST['post'];
+    }
+    else if (isset($_REQUEST['lp_id']))
+    {
+        $post_id = $_REQUEST['lp_id'];
+    }
+    else if (isset($_REQUEST['post_id']))
+    {
+        $post_id = $_REQUEST['post_id'];
+    }
 
 
-	if ($current_variation_id>0)
-		$main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
+    if ($current_variation_id>0)
+        $main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
 
-	if (!$main_headline)
-	{
-		get_post_meta($post_id,'lp-main-headline', true);
-	}
+    if (!$main_headline)
+    {
+        get_post_meta($post_id,'lp-main-headline', true);
+    }
 
 
-	return $main_headline;
+    return $main_headline;
 }
 
 add_action('init','lp_ab_testing_add_rewrite_rules');
 function lp_ab_testing_add_rewrite_rules()
 {
-	$this_path = LANDINGPAGES_PATH;
-	$this_path = explode('wp-content',$this_path);
-	$this_path = "wp-content".$this_path[1];
-
-	$slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
-	//echo $slug;exit;
-	$ab_testing = get_option( 'lp-main-landing-page-disable-turn-off-ab', "0");
-	if($ab_testing === "0") {
-	add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2",'top');
-	add_rewrite_rule("$slug/([^/]*)?", $this_path."modules/module.redirect-ab-testing.php?permalink_name=$1 ",'top');
-	add_rewrite_rule("landing-page=([^/]*)?", $this_path.'modules/module.redirect-ab-testing.php?permalink_name=$1','top');
-	}
-	add_filter('mod_rewrite_rules', 'lp_ab_testing_modify_rules', 1);
-	function lp_ab_testing_modify_rules($rules)
-	{
-		if (!stristr($rules,'RewriteCond %{QUERY_STRING} !lp-variation-id'))
-		{
-			$rules_array = preg_split ('/$\R?^/m', $rules);
-			if (count($rules_array)<3)
-			{
-				$rules_array = explode("\n", $rules);
-				$rules_array = array_filter($rules_array);
-			}
-
-			//print_r($rules_array);exit;
-
-			$this_path = LANDINGPAGES_PATH;
-			$this_path = explode('wp-content',$this_path);
-			$this_path = "wp-content".$this_path[1];
-			$slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
-
-			$i = 0;
-			foreach ($rules_array as $key=>$val)
-			{
-
-				if ( stristr($val,"RewriteRule ^{$slug}/([^/]*)? ") ||  stristr($val,"RewriteRule ^{$slug}/([^/]*)/([0-9]+)/ ") )
-				{
-					$new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
-					$rules_array[$i] = $new_val;
-					$i++;
-					$rules_array[$i] = $val;
-					$i++;
-				}
-				else
-				{
-					$rules_array[$i] = $val;
-					$i++;
-				}
-			}
-
-			$rules = implode("\r\n", $rules_array);
-		}
-
-		return $rules;
-	}
+    $this_path = LANDINGPAGES_PATH;
+    $this_path = explode('wp-content',$this_path);
+    $this_path = "wp-content".$this_path[1];
+
+    $slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
+    //echo $slug;exit;
+    $ab_testing = get_option( 'lp-main-landing-page-disable-turn-off-ab', "0");
+    if($ab_testing === "0") {
+        add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2",'top');
+        add_rewrite_rule("$slug/([^/]*)?", $this_path."modules/module.redirect-ab-testing.php?permalink_name=$1 ",'top');
+        add_rewrite_rule("landing-page=([^/]*)?", $this_path.'modules/module.redirect-ab-testing.php?permalink_name=$1','top');
+    }
+    add_filter('mod_rewrite_rules', 'lp_ab_testing_modify_rules', 1);
+    function lp_ab_testing_modify_rules($rules)
+    {
+        if (!stristr($rules,'RewriteCond %{QUERY_STRING} !lp-variation-id'))
+        {
+            $rules_array = preg_split ('/$\R?^/m', $rules);
+            if (count($rules_array)<3)
+            {
+                $rules_array = explode("\n", $rules);
+                $rules_array = array_filter($rules_array);
+            }
+
+            //print_r($rules_array);exit;
+
+            $this_path = LANDINGPAGES_PATH;
+            $this_path = explode('wp-content',$this_path);
+            $this_path = "wp-content".$this_path[1];
+            $slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
+
+            $i = 0;
+            foreach ($rules_array as $key=>$val)
+            {
+
+                if ( stristr($val,"RewriteRule ^{$slug}/([^/]*)? ") ||  stristr($val,"RewriteRule ^{$slug}/([^/]*)/([0-9]+)/ ") )
+                {
+                    $new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
+                    $rules_array[$i] = $new_val;
+                    $i++;
+                    $rules_array[$i] = $val;
+                    $i++;
+                }
+                else
+                {
+                    $rules_array[$i] = $val;
+                    $i++;
+                }
+            }
+
+            $rules = implode("\r\n", $rules_array);
+        }
+
+        return $rules;
+    }
 
 }
 
 
 add_filter('lp_selected_template','lp_ab_testing_get_selected_template');//get correct selected template for each variation
 function lp_ab_testing_get_selected_template($template)
 {
-	global $post;
+    global $post;
 
-	$current_variation_id = lp_ab_testing_get_current_variation_id();
+    $current_variation_id = lp_ab_testing_get_current_variation_id();
 
-	if ($current_variation_id>0)
-	{
-		$new_template =  get_post_meta($post->ID, 'lp-selected-template-'.$current_variation_id, true);
-		if ($new_template)
-			$template = $new_template;
-	}
+    if ($current_variation_id>0)
+    {
+        $new_template =  get_post_meta($post->ID, 'lp-selected-template-'.$current_variation_id, true);
+        if ($new_template)
+            $template = $new_template;
+    }
 
-	return $template;
+    return $template;
 }
 
 //prepare custom js and css for
 add_filter('lp_custom_js_name','lp_ab_testing_prepare_name');
 add_filter('lp_custom_css_name','lp_ab_testing_prepare_name');
 function lp_ab_testing_prepare_name($id)
 {
-	$current_variation_id = lp_ab_testing_get_current_variation_id();
-	//echo $current_variation_id;exit;
-	if ($current_variation_id>0)
-	{
-		$id = $id.'-'.$current_variation_id;
-	}
-
-	return $id;
+    $current_variation_id = lp_ab_testing_get_current_variation_id();
+    //echo $current_variation_id;exit;
+    if ($current_variation_id>0)
+    {
+        $id = $id.'-'.$current_variation_id;
+    }
+
+    return $id;
 }
 
 add_action('wp_ajax_lp_ab_testing_prepare_variation', 'lp_ab_testing_prepare_variation_callback');
 add_action('wp_ajax_nopriv_lp_ab_testing_prepare_variation', 'lp_ab_testing_prepare_variation_callback');
 
 function lp_ab_testing_prepare_variation_callback()
 {
 
-	$page_id = lp_url_to_postid( trim($_POST['current_url']) );
+    $page_id = lp_url_to_postid( trim($_POST['current_url']) );
 
-	$variations = get_post_meta($page_id,'lp-ab-variations', true);
-	$marker = get_post_meta($page_id,'lp-ab-variations-marker', true);
-	if (!is_numeric($marker)) {
-		$marker = 0;
-	}
+    $variations = get_post_meta($page_id,'lp-ab-variations', true);
+    $marker = get_post_meta($page_id,'lp-ab-variations-marker', true);
+    if (!is_numeric($marker)) {
+        $marker = 0;
+    }
 
-	if ($variations)
-	{
-		//echo $variations;
-		$variations = explode(',',$variations);
-		//print_r($variations);
+    if ($variations)
+    {
+        //echo $variations;
+        $variations = explode(',',$variations);
+        //print_r($variations);
 
-		$variation_id = $variations[$marker];
+        $variation_id = $variations[$marker];
 
-		$marker++;
+        $marker++;
 
-		if ($marker>=count($variations))
-		{
-			//echo "here";
-			$marker = 0;
-		}
+        if ($marker>=count($variations))
+        {
+            //echo "here";
+            $marker = 0;
+        }
 
-		update_post_meta($page_id, 'lp-ab-variations-marker', $marker);
+        update_post_meta($page_id, 'lp-ab-variations-marker', $marker);
 
-		echo $variation_id;
-		die();
-	}
+        echo $variation_id;
+        die();
+    }
 
 
 }
 
 
 add_filter('the_content','lp_ab_testing_alter_content_area', 10, 2);
 add_filter('get_the_content','lp_ab_testing_alter_content_area', 10, 2);
 function lp_ab_testing_alter_content_area($content)
 {
-	global $post;
+    global $post;
 
-	if ( !isset($post) || $post->post_type != 'landing-page' ) {
-		return $content;
-	}
+    if ( !isset($post) || $post->post_type != 'landing-page' ) {
+        return $content;
+    }
 
-	$variation_id = lp_ab_testing_get_current_variation_id();
+    $variation_id = lp_ab_testing_get_current_variation_id();
 
-	if ($variation_id>0)
-	{
-		$content = do_shortcode(get_post_meta($post->ID,'content-'.$variation_id, true));
-	}
+    if ($variation_id>0)
+    {
+        $content = do_shortcode(get_post_meta($post->ID,'content-'.$variation_id, true));
+    }
 
-	return $content;
+    return $content;
 }
 
 add_filter('wp_title','lp_ab_testing_alter_title_area', 9, 2);
 add_filter('the_title','lp_ab_testing_alter_title_area', 10, 2);
 add_filter('get_the_title','lp_ab_testing_alter_title_area', 10, 2);
 function lp_ab_testing_alter_title_area( $content , $id = null)
 {
-	global $post;
+    global $post;
 
-	if (!isset($post))
-		return $content;
+    if (!isset($post))
+        return $content;
 
-	if ( ( $post->post_type!='landing-page'||is_admin()) || $id != $post->ID)
-		return $content;
+    if ( ( $post->post_type!='landing-page'||is_admin()) || $id != $post->ID)
+        return $content;
 
-	return lp_main_headline($post, null, true);
+    return lp_main_headline($post, null, true);
 }
 
 add_action('lp_record_impression','lp_ab_testing_record_impression', 10, 3 );
 function lp_ab_testing_record_impression($post_id, $post_type = 'landing-page' , $variation_id = 0 ) {
 
-	/* If Landing Page Post Type */
-	if ( $post_type == 'landing-page' ) {
-		$meta_key = 'lp-ab-variation-impressions-'.$variation_id;
-	}
-	/* If Non Landing Page Post Type */
-	else  {
-		$meta_key = '_inbound_impressions_count';
-	}
+    /* If Landing Page Post Type */
+    if ( $post_type == 'landing-page' ) {
+        $meta_key = 'lp-ab-variation-impressions-'.$variation_id;
+    }
+    /* If Non Landing Page Post Type */
+    else  {
+        $meta_key = '_inbound_impressions_count';
+    }
 
-	$impressions = get_post_meta($post_id, $meta_key , true);
+    $impressions = get_post_meta($post_id, $meta_key , true);
 
-	if (!is_numeric($impressions)) {
-		$impressions = 1;
-	} else {
-		$impressions++;
-	}
+    if (!is_numeric($impressions)) {
+        $impressions = 1;
+    } else {
+        $impressions++;
+    }
 
-	update_post_meta($post_id, $meta_key , $impressions);
+    update_post_meta($post_id, $meta_key , $impressions);
 }
 
 
 add_action('lp_launch_customizer_pre','lp_ab_testing_customizer_enqueue');
 function lp_ab_testing_customizer_enqueue($post) {
 
-	$permalink = get_permalink( $post->ID );
-	$randomstring = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
+    $permalink = get_permalink( $post->ID );
+    $randomstring = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
 
-	wp_enqueue_script( 'lp_ab_testing_customizer_js', LANDINGPAGES_URLPATH . 'js/customizer.ab-testing.js', array( 'jquery' ) );
-	wp_localize_script( 'lp_ab_testing_customizer_js', 'ab_customizer', array( 'lp_id' => $post->ID ,'permalink' => $permalink , 'randomstring' => $randomstring));
-	wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'css/customizer-ab-testing.css');
+    wp_enqueue_script( 'lp_ab_testing_customizer_js', LANDINGPAGES_URLPATH . 'js/customizer.ab-testing.js', array( 'jquery' ) );
+    wp_localize_script( 'lp_ab_testing_customizer_js', 'ab_customizer', array( 'lp_id' => $post->ID ,'permalink' => $permalink , 'randomstring' => $randomstring));
+    wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'css/customizer-ab-testing.css');
 }
\ No newline at end of file
diff --git a/modules/module.install.php b/modules/module.install.php
index e13030a..bf563f0 100644
--- a/modules/module.install.php
+++ b/modules/module.install.php
@@ -1,81 +1,89 @@
 <?php
 // Added Demo Landing on Install
 add_action('admin_init', 'inbound_create_default_post_type');
 function inbound_create_default_post_type(){
-
-    $current_user = wp_get_current_user();
+	
 
     $lp_default_options = get_option( 'lp_settings_general' );
 
     if ( isset( $lp_default_options["default_landing_page"] ) ) {
         return $lp_default_options["default_landing_page"];
     }
 
-    $default_lander = wp_insert_post(
-            array(
-                'post_title'     => __( 'A/B Testing Landing Page Example' , 'landing-pages'),
-                'post_content'   => __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages'),
-                'post_status'    => 'publish',
-                'post_author'    => $current_user->ID,
-                'post_type'      => 'landing-page',
-                'comment_status' => 'closed'
-            )
-        );
+	return inbound_install_example_lander();
+}
+
+/**
+*  Install example landing page and return landing page id
+*/
+function inbound_install_example_lander() {
+
+	
+	$landing_page_id = wp_insert_post(
+        array(
+            'post_title'     => __( 'A/B Testing Landing Page Example' , 'landing-pages'),
+            'post_content'   => __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'post'),
+            'post_status'    => 'publish',
+            'post_type'      => 'landing-page',
+            'comment_status' => 'closed'
+        )
+    );
+	
 
     // Variation A
-    add_post_meta($default_lander, 'lp-main-headline', __( 'Main Catchy Headline (A)' , 'landing-pages') );
-    add_post_meta($default_lander, 'lp-selected-template', 'svtle');
-    add_post_meta($default_lander, 'svtle-conversion-area-content', '<h2>'.__( 'Form a' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]' );
-    add_post_meta($default_lander, 'svtle-main-content', __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages') );
+    add_post_meta($landing_page_id, 'lp-main-headline', __( 'Main Catchy Headline (A)' , 'landing-pages') );
+    add_post_meta($landing_page_id, 'lp-selected-template', 'svtle');
+    add_post_meta($landing_page_id, 'svtle-conversion-area-content', '<h2>'.__( 'Form a' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]' );
+    add_post_meta($landing_page_id, 'svtle-main-content', __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages') );
 
     // variation B
-    add_post_meta($default_lander, 'lp-main-headline-1', __('Main Catchy Headline Two (B)' , 'landing-pages') );
-    add_post_meta($default_lander, 'lp-selected-template-1', 'svtle');
-    add_post_meta($default_lander, 'svtle-conversion-area-content-1', '<h2>'.__( 'Form B' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]');
-    add_post_meta($default_lander, 'svtle-main-content-1', '<p>(Version B) This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>');
+    add_post_meta($landing_page_id, 'lp-main-headline-1', __('Main Catchy Headline Two (B)' , 'landing-pages') );
+    add_post_meta($landing_page_id, 'lp-selected-template-1', 'svtle');
+    add_post_meta($landing_page_id, 'svtle-conversion-area-content-1', '<h2>'.__( 'Form B' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]');
+    add_post_meta($landing_page_id, 'svtle-main-content-1', '<p>(Version B) This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>');
 
     // Add A/B Testing meta
-    add_post_meta($default_lander, 'lp-ab-variations', '0,1');
-    add_post_meta($default_lander, 'lp-ab-variation-impressions-0', 30);
-    add_post_meta($default_lander, 'lp-ab-variation-impressions-1', 35);
-    add_post_meta($default_lander, 'lp-ab-variation-conversions-0', 10);
-    add_post_meta($default_lander, 'lp-ab-variation-conversions-1', 15);
+    add_post_meta($landing_page_id, 'lp-ab-variations', '0,1');
+    add_post_meta($landing_page_id, 'lp-ab-variation-impressions-0', 30);
+    add_post_meta($landing_page_id, 'lp-ab-variation-impressions-1', 35);
+    add_post_meta($landing_page_id, 'lp-ab-variation-conversions-0', 10);
+    add_post_meta($landing_page_id, 'lp-ab-variation-conversions-1', 15);
 
     // Add template meta A
-    add_post_meta($default_lander, 'svtle-submit-button-color', '5baa1e');
-    add_post_meta($default_lander, 'svtle-display-social', '0');
-    add_post_meta($default_lander, 'svtle-logo', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
-    add_post_meta($default_lander, 'svtle-body-color', 'ffffff');
-    add_post_meta($default_lander, 'svtle-sidebar', 'left');
-    add_post_meta($default_lander, 'svtle-page-text-color', '4d4d4d');
-    add_post_meta($default_lander, 'svtle-sidebar-color', 'ffffff');
-    add_post_meta($default_lander, 'svtle-sidebar-text-color', '000000');
-    add_post_meta($default_lander, 'svtle-header-color', 'ffffff');
+    add_post_meta($landing_page_id, 'svtle-submit-button-color', '5baa1e');
+    add_post_meta($landing_page_id, 'svtle-display-social', '0');
+    add_post_meta($landing_page_id, 'svtle-logo', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
+    add_post_meta($landing_page_id, 'svtle-body-color', 'ffffff');
+    add_post_meta($landing_page_id, 'svtle-sidebar', 'left');
+    add_post_meta($landing_page_id, 'svtle-page-text-color', '4d4d4d');
+    add_post_meta($landing_page_id, 'svtle-sidebar-color', 'ffffff');
+    add_post_meta($landing_page_id, 'svtle-sidebar-text-color', '000000');
+    add_post_meta($landing_page_id, 'svtle-header-color', 'ffffff');
 
     // Add template meta B
-    add_post_meta($default_lander, 'svtle-submit-button-color-1', 'ff0c00');
-    add_post_meta($default_lander, 'svtle-display-social-1', '0');
-    add_post_meta($default_lander, 'svtle-logo-1', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
-    add_post_meta($default_lander, 'svtle-body-color-1', '51b0ef');
-    add_post_meta($default_lander, 'svtle-sidebar-1', 'left');
-    add_post_meta($default_lander, 'svtle-page-text-color-1', '000000');
-    add_post_meta($default_lander, 'svtle-sidebar-color-1', '51b0ef');
-    add_post_meta($default_lander, 'svtle-sidebar-text-color-1', '000000');
-    add_post_meta($default_lander, 'svtle-header-color-1', '51b0ef');
+    add_post_meta($landing_page_id, 'svtle-submit-button-color-1', 'ff0c00');
+    add_post_meta($landing_page_id, 'svtle-display-social-1', '0');
+    add_post_meta($landing_page_id, 'svtle-logo-1', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
+    add_post_meta($landing_page_id, 'svtle-body-color-1', '51b0ef');
+    add_post_meta($landing_page_id, 'svtle-sidebar-1', 'left');
+    add_post_meta($landing_page_id, 'svtle-page-text-color-1', '000000');
+    add_post_meta($landing_page_id, 'svtle-sidebar-color-1', '51b0ef');
+    add_post_meta($landing_page_id, 'svtle-sidebar-text-color-1', '000000');
+    add_post_meta($landing_page_id, 'svtle-header-color-1', '51b0ef');
 
 
     // Store our page IDs
     $options = array(
-        "default_landing_page" => $default_lander
+        "default_landing_page" => $landing_page_id
     );
 
-    update_option( "lp_settings_general", $options );
+	
+    update_option( "lp_settings_general" , $options );
 
-    return $default_lander;
+    return $landing_page_id;
 }
-
 /**
  * Debug Activation errors */
 //update_option('plugin_error',  ''); //clear
 /*
 add_action('activated_plugin','activation_save_error');
@@ -111,32 +119,32 @@ function lp_install_register_required_plugins() {
      * If the source is NOT from the .org repo, then source is also required.
      */
     $plugins = array(
 
         // This is an example of how to include a plugin pre-packaged with a theme
-      /*  array(
-            'name'                  => 'TGM Example Plugin', // The plugin name
-            'slug'                  => 'tgm-example-plugin', // The plugin slug (typically the folder name)
-            'source'                => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
-            'required'              => true, // If false, the plugin is only 'recommended' instead of required
-            'version'               => '', // E.g. 1.0.0. If set, the active plugin must be this version or higher, otherwise a notice is presented
-            'force_activation'      => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch
-            'force_deactivation'    => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins
-            'external_url'          => '', // If set, overrides default API URL and points to an external URL
-        ), */
+        /*  array(
+              'name'                  => 'TGM Example Plugin', // The plugin name
+              'slug'                  => 'tgm-example-plugin', // The plugin slug (typically the folder name)
+              'source'                => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
+              'required'              => true, // If false, the plugin is only 'recommended' instead of required
+              'version'               => '', // E.g. 1.0.0. If set, the active plugin must be this version or higher, otherwise a notice is presented
+              'force_activation'      => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch
+              'force_deactivation'    => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins
+              'external_url'          => '', // If set, overrides default API URL and points to an external URL
+          ), */
 
         // This is an example of how to include a plugin from the WordPress Plugin Repository
         array(
             'name'      => __('WordPress Leads' , 'landing-pages') .' <span class=\'inbound-install-notice\'> - '. __('This <b>free</b> landing page addon will give you the ability to track and manage incoming web leads. Gather advanced Lead Intelligence and close more deals.' , 'landing-pages') .' <a class=\'inbound-install-notice-links\' href=\'http://wordpress.org/plugins/leads/\'> '. __('Learn more about WordPress Leads' , 'landing-pages') .'</a></span>',
             'slug'      => 'leads',
             'required'  => false,
         ),
-       array(
-           'name'      => __('WordPress Calls to Action' , 'landing-pages') .' <span class=\'inbound-install-notice\'> - '. __('This <b>free</b> landing page addon will drive more traffic into your Landing Pages with Targeted Calls to Action in your sites sidebars & content. Create popups to capture visitor attention and convert more leads.' , 'landing-pages') . ' <a class=\'inbound-install-notice-links\' href=\'http://wordpress.org/plugins/cta/\'> ' . __('Learn more about WordPress Calls to Action' , 'landing-pages') . '</a></span>',
-           'slug'      => 'cta',
-           'required'  => false,
-       ),
+        array(
+            'name'      => __('WordPress Calls to Action' , 'landing-pages') .' <span class=\'inbound-install-notice\'> - '. __('This <b>free</b> landing page addon will drive more traffic into your Landing Pages with Targeted Calls to Action in your sites sidebars & content. Create popups to capture visitor attention and convert more leads.' , 'landing-pages') . ' <a class=\'inbound-install-notice-links\' href=\'http://wordpress.org/plugins/cta/\'> ' . __('Learn more about WordPress Calls to Action' , 'landing-pages') . '</a></span>',
+            'slug'      => 'cta',
+            'required'  => false,
+        ),
 
     );
 
     // Change this to your theme text domain, used for internationalising strings
     $theme_text_domain = 'landing-pages';
@@ -173,11 +181,11 @@ function lp_install_register_required_plugins() {
             'install_link'                              => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ),
             'activate_link'                             => _n_noop( 'Activate installed plugin', 'Activate installed plugins' ),
             'return'                                    => __( 'Return to Required Plugins Installer', $theme_text_domain ),
             'plugin_activated'                          => __( 'Plugin activated successfully.', $theme_text_domain ),
             'complete'                                  => __( 'All plugins installed and activated successfully. %s', $theme_text_domain ),
-             // %1$s = dashboard link
+            // %1$s = dashboard link
         )
     );
 
     tgmpa( $plugins, $config );
 
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7490be9..655e7ca 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,8 +1,8 @@
-<phpunit bootstrap="tests/travis-ci/bootstrap.php" backupGlobals="false" colors="true">
+<phpunit bootstrap="tests/phpunit/bootstrap.php" backupGlobals="false" colors="true">
     <testsuites>
         <!-- Default test suite to run all tests -->
         <testsuite>
-            <directory prefix="test." suffix=".php">tests/travis-ci/</directory>
+            <directory prefix="test." suffix=".php">tests/phpunit/</directory>
         </testsuite>
     </testsuites>
 </phpunit>
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
index b4abb7e..01d0777 100644
--- a/readme.txt
+++ b/readme.txt
@@ -5,11 +5,11 @@ Donate link: mailto:marketplace@inboundnow.com
 License: GPLv2 or later
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 Tags: landing pages, inbound marketing, conversion pages, split testing, a b test, a b testing, a/b test, a/b testing, coming soon page, email list, landing page, list building, maintenance page, squeeze page, inbound now, landing-pages, splash pages, cpa, click tracking, goal tracking, analytics, free landing page templates
 Requires at least: 3.8
 Tested up to: 4.2
-Stable Tag: 1.8.6
+Stable Tag: 1.8.8
 
 Create landing pages for your WordPress site. Monitor and improve conversion rates, run A/B split tests, customize your own templates and more.
 
 == Description ==
 
@@ -70,10 +70,13 @@ The plugin is also fully extendable and has a number of actions, filters, and ho
 2. Track conversion rates and continuously improve your landing pages
 3. Manage Split Testing Page
 4. Choose from a ton of pre-made templates, use your existing design, or design your own theme!
 
 == Changelog ==
+= 1.8.8 =
+* Security Patch for XSS in firefox
+
 = 1.8.6 =
 * Security Patch
 
 = 1.8.5 =
 * Security Patch
diff --git a/shared/assets/css/admin/global-inbound-admin.css b/shared/assets/css/admin/global-inbound-admin.css
index 9e03bf2..82cbed5 100644
--- a/shared/assets/css/admin/global-inbound-admin.css
+++ b/shared/assets/css/admin/global-inbound-admin.css
@@ -1,154 +1,192 @@
 #wpadminbar.nojs .ab-top-menu > li.menupop.inbound-nav-marketing:hover > .ab-item,
 #wpadminbar .ab-top-menu > li.menupop.inbound-nav-marketing.hover > .ab-item,
 #wpadminbar.nojs .ab-top-menu > li.menupop.inbound-nav-marketing > .ab-item,
 #wpadminbar .ab-top-menu > li.menupop.inbound-nav-marketing > .ab-item, #inboundnow-media-button {
 
-  background-image: url('../../images/global/shortcodes-blue.png');
+    background-image: url('../../images/global/shortcodes-blue.png');
 
-  background-repeat: no-repeat;
-  background-position: 0.15em 50%;
-  padding-left: 22px;
+    background-repeat: no-repeat;
+    background-position: 0.15em 50%;
+    padding-left: 22px;
 }
+
 #inboundnow-media-button {
-  padding-left: 5px;
+    padding-left: 5px;
 }
-.inbound-nav-marketing div:first-of-type{
-  color:rgba(240,245,250,1);
+
+.inbound-nav-marketing div:first-of-type {
+    color: rgba(240, 245, 250, 1);
 }
+
 body #calls-to-action .toggle .switch-versions, body #landing-pages .toggle .switch-versions, body #leads .toggle .switch-versions {
- display: none;
+    display: none;
 }
- .switch-versions,  .switch-versions {
+
+.switch-versions, .switch-versions {
 
 }
+
 #wp-admin-bar-ddw-edd-languages-de > .ab-item:before,
 #wp-admin-bar-ddw-edd-translations-forum > .ab-item:before {
-  color: #ff9900;
-  content: '• ';
+    color: #ff9900;
+    content: '• ';
 }
+
 #wpadminbar .inbound-search-input {
-  width: 140px;
+    width: 140px;
 }
+
 #wp-admin-bar-ddw-edd-inboundsupportsections .ab-item,
 #wp-admin-bar-ddw-edd-inbounddocsquick .ab-item,
 #wp-admin-bar-ddw-edd-inbounddocssections .ab-item,
 #wpadminbar .inbound-search-input,
 #wpadminbar .inbound-search-go {
-  color: #21759b !important;
-  text-shadow: none;
+    color: #21759b !important;
+    text-shadow: none;
 }
+
 #wpadminbar .inbound-search-input,
 #wpadminbar .inbound-search-go {
-  background-color: #fff;
-  height: 18px;
-  line-height: 18px;
-  padding: 1px 4px;
+    background-color: #fff;
+    height: 18px;
+    line-height: 18px;
+    padding: 1px 4px;
 }
+
 #wpadminbar .inbound-search-go {
-  -webkit-border-radius: 11px;
-     -moz-border-radius: 11px;
-          border-radius: 11px;
-  font-size: 0.67em;
-  margin: 0 0 0 2px;
+    -webkit-border-radius: 11px;
+    -moz-border-radius: 11px;
+    border-radius: 11px;
+    font-size: 0.67em;
+    margin: 0 0 0 2px;
 }
+
 @font-face {
-  font-family: 'FontAwesome';
-  src: url('../../fonts/fontawesome/fontawesome-webfont.eot');
-  src: url('../../fonts/fontawesome/fontawesome-webfont.eot') format('embedded-opentype'),
-  url('../../fonts/fontawesome/fontawesome-webfont.woff?v=3.0.2') format('woff'),
-  url('../../fonts/fontawesome/fontawesome-webfont.ttf?v=3.0.2') format('truetype');
-  font-weight: normal;
-  font-style: normal;
+    font-family: 'FontAwesome';
+    src: url('../../fonts/fontawesome/fontawesome-webfont.eot');
+    src: url('../../fonts/fontawesome/fontawesome-webfont.eot') format('embedded-opentype'),
+    url('../../fonts/fontawesome/fontawesome-webfont.woff?v=3.0.2') format('woff'),
+    url('../../fonts/fontawesome/fontawesome-webfont.ttf?v=3.0.2') format('truetype');
+    font-weight: normal;
+    font-style: normal;
 }
+
 #adminmenu .menu-icon-wp-lead div.wp-menu-image:before {
-  font-family: "FontAwesome" !important;
-  content: "\f0c0";
+    font-family: "FontAwesome" !important;
+    content: "\f0c0";
 
 }
+
 .branch-3-7 #adminmenu .menu-icon-wp-lead div.wp-menu-image:before {
-display: none;
+    display: none;
 }
-#adminmenu .menu-icon-wp-lead div.wp-menu-image img{
-  display: none;
+
+#adminmenu .menu-icon-wp-lead div.wp-menu-image img {
+    display: none;
 }
+
 .branch-3-7 #adminmenu .menu-icon-wp-lead div.wp-menu-image img {
-  display: block;
+    display: block;
 }
+
 #wp-admin-bar-inbound-cta a:first-child, #wp-admin-bar-inbound-templates .ab-item.ab-empty-item, #wp-admin-bar-inbound-settings .ab-item.ab-empty-item, #wp-admin-bar-inbound-analytics a:first-child {
-  padding-left: 30px !important;
+    padding-left: 30px !important;
 }
+
 #wp-admin-bar-inbound-templates .ab-item.ab-empty-item:hover, #wp-admin-bar-inbound-settings .ab-item.ab-empty-item:hover {
-  color: #2ea2cc;
+    color: #2ea2cc;
 }
+
 #wp-admin-bar-inbound-leads a:first-child, #wp-admin-bar-inbound-seo a:first-child, #wp-admin-bar-inbound-landingpages a:first-child, #wp-admin-bar-inbound-forms a:first-child {
-  padding-left: 31px !important;
+    padding-left: 31px !important;
 }
+
 #search-inbound-menu {
-  max-height: 22px !important;
-  padding: 0px !important;
-  min-height: 23px !important;
-  padding-left: 3px !important;
-  margin-bottom: 1px !important;
-}
-#wp-admin-bar-inbound-docs-searchform, #wp-admin-bar-inbound-leads-search{
-  margin-bottom: 10px !important;
-}
-#wp-admin-bar-inbound-cta .ab-submenu a, #wp-admin-bar-inbound-leads .ab-submenu a,  #wp-admin-bar-inbound-landingpages .ab-submenu a , #wp-admin-bar-inbound-forms .ab-submenu a, #wp-admin-bar-inbound-templates .ab-submenu a,  #wp-admin-bar-inbound-analytics .ab-submenu a, #wp-admin-bar-inbound-seo .ab-submenu a{
-  padding-left: 10px !important;
-}
- #wp-admin-bar-inbound-cta:before, #wp-admin-bar-inbound-leads:before, #wp-admin-bar-inbound-landingpages:before, #wp-admin-bar-inbound-forms:before, #wp-admin-bar-inbound-templates:before, #wp-admin-bar-inbound-settings:before, #wp-admin-bar-inbound-analytics:before, #wp-admin-bar-inbound-seo:before  {
-  font-family: "FontAwesome" !important;
-  content: "\f05b" !important;
-  font: 100 19px/1 "FontAwesome" !important;
-  padding-top: 4px;
-  width: 30px;
-  display: inline-block;
-  height: 30px;
-  position: absolute;
-  left: 6px;
+    max-height: 22px !important;
+    padding: 0px !important;
+    min-height: 23px !important;
+    padding-left: 3px !important;
+    margin-bottom: 1px !important;
+}
+
+#wp-admin-bar-inbound-docs-searchform, #wp-admin-bar-inbound-leads-search {
+    margin-bottom: 10px !important;
 }
+
+#wp-admin-bar-inbound-cta .ab-submenu a, #wp-admin-bar-inbound-leads .ab-submenu a, #wp-admin-bar-inbound-landingpages .ab-submenu a, #wp-admin-bar-inbound-forms .ab-submenu a, #wp-admin-bar-inbound-templates .ab-submenu a, #wp-admin-bar-inbound-analytics .ab-submenu a, #wp-admin-bar-inbound-seo .ab-submenu a {
+    padding-left: 10px !important;
+}
+
+#wp-admin-bar-inbound-cta:before, #wp-admin-bar-inbound-leads:before, #wp-admin-bar-inbound-landingpages:before, #wp-admin-bar-inbound-forms:before, #wp-admin-bar-inbound-templates:before, #wp-admin-bar-inbound-settings:before, #wp-admin-bar-inbound-analytics:before, #wp-admin-bar-inbound-seo:before {
+    font-family: "FontAwesome" !important;
+    content: "\f05b" !important;
+    font: 100 19px/1 "FontAwesome" !important;
+    padding-top: 4px;
+    width: 30px;
+    display: inline-block;
+    height: 30px;
+    position: absolute;
+    left: 6px;
+}
+
 #wp-admin-bar-inbound-leads:before {
-  content: "\f0c0" !important;
-  font: 100 17px/1 "FontAwesome" !important;
+    content: "\f0c0" !important;
+    font: 100 17px/1 "FontAwesome" !important;
 }
+
 #wp-admin-bar-inbound-landingpages:before {
-  content: "\f15c" !important;
-  left: 7px;
-  font-size: 21px !important;
-  }
+    content: "\f15c" !important;
+    left: 7px;
+    font-size: 21px !important;
+}
+
 #wp-admin-bar-inbound-forms:before {
-    font: 400 18px/1 dashicons!important;
+    font: 400 18px/1 dashicons !important;
     content: "\f163" !important;
-  }
+}
+
 #wp-admin-bar-inbound-templates:before {
     content: "\f0c5" !important;
     font-size: 18px !important;
-  }
+}
+
 #wp-admin-bar-inbound-settings:before {
-  content: "\f013" !important;
-  left: 7px !important;
+    content: "\f013" !important;
+    left: 7px !important;
 }
+
 #wp-admin-bar-inbound-analytics:before {
-  content: "\f012" !important;
-  font-size: 17px !important;
+    content: "\f012" !important;
+    font-size: 17px !important;
 }
+
 #wp-admin-bar-inbound-seo:before {
-  content: "\f002" !important;
-  font-size: 17px !important;
+    content: "\f002" !important;
+    font-size: 17px !important;
 }
+
 #wp-admin-bar-inbound-cta a {
-  vertical-align: top;
+    vertical-align: top;
 }
+
 #adminmenu .menu-icon-wp-call-to-action div.wp-menu-image:before {
-  font-family: "FontAwesome" !important;
-  content: "\f05b";
-  font: 400 24px/1 "FontAwesome" !important;
-  padding-top: 6px;
+    font-family: "FontAwesome" !important;
+    content: "\f05b";
+    font: 400 24px/1 "FontAwesome" !important;
+    padding-top: 6px;
 
 }
+
 .short-list-inbound .mceIcon {
-position: absolute;
-top: 0;
-left: 0;
-width: 22px;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 22px;
+}
+
+.inbound-form-shortcode input {
+    overflow:hidden;
+}
+.inbound-form-shortcode  {
+    overflow:hidden;
 }
\ No newline at end of file
diff --git a/shared/shortcodes/inbound-shortcodes.php b/shared/shortcodes/inbound-shortcodes.php
index f5e6103..8782d02 100644
--- a/shared/shortcodes/inbound-shortcodes.php
+++ b/shared/shortcodes/inbound-shortcodes.php
@@ -75,11 +75,11 @@ class Inbound_Shortcodes {
 			wp_enqueue_script('jquery-ui-sortable' );
 			wp_enqueue_script('inbound-shortcodes-plugins', INBOUNDNOW_SHARED_URLPATH . 'shortcodes/js/shortcodes-plugins.js', array( 'jquery', 'jquery-cookie' ));
 
 			if (isset($post)&&post_type_supports($post->post_type,'editor')||isset($post)&&'wp-call-to-action' === $post->post_type) {
 				wp_enqueue_script('inbound-shortcodes', INBOUNDNOW_SHARED_URLPATH . 'shortcodes/js/shortcodes.js', array( 'jquery', 'jquery-cookie' ));
-				$form_id = (isset($_GET['post'])) ? $_GET['post'] : '';
+				$form_id = (isset($_GET['post']) && is_int( $_GET['post'] )) ? $_GET['post'] : ''; 
 				wp_localize_script( 'inbound-shortcodes', 'inbound_shortcodes', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) , 'adminurl' => admin_url(), 'inbound_shortcode_nonce' => wp_create_nonce('inbound-shortcode-nonce') , 'form_id' => $form_id ) );
 				wp_enqueue_script('selectjs', INBOUNDNOW_SHARED_URLPATH . 'shortcodes/js/select2.min.js');
 				wp_enqueue_style('selectjs', INBOUNDNOW_SHARED_URLPATH . 'shortcodes/css/select2.css');
 			}
 
@@ -655,10 +655,24 @@ class Inbound_Shortcodes {
 				}
 				?>
 			</ol>
 		</div>
 		<div id="inbound-email-response">
+		    <?php
+
+            if (defined('INBOUND_PRO_PATH')) {
+            ?>
+            <h3><?php _e( 'Inbound Pro Users' , INBOUNDNOW_TEXT_DOMAIN ); ?></h3>
+            <div class='' style='padding-left:20px;'>
+
+                <?php echo sprintf( __( ' Membership holders should ignore the setup area below and referrer to %s this document %s for instructions on setting up a followup email. We are leaveing this section in up for non members and for members that are leveraging it. We may remove it remove it entirely from the Inbound Pro plugin. ' , INBOUNDNOW_TEXT_DOMAIN ) , '<a href="http://docs.inboundnow.com/guide/creating-a-follow-up-email-using-inbound-now-as-an-autoresponder-marketing-automation/">', '</a>') ; ?>
+            </div>
+            <br>
+            <?php
+            }
+            ?>
+
 			<h2><?php _e( 'Set Email Response to Send to the person filling out the form' , INBOUNDNOW_TEXT_DOMAIN ); ?></h2>
 			<?php
 			$values = get_post_custom( $post->ID );
 			$selected = isset( $values['inbound_email_send_notification'] ) ? esc_attr( $values['inbound_email_send_notification'][0] ) : "";
 			$email_subject = get_post_meta( $post->ID, 'inbound_confirmation_subject', TRUE );
@@ -756,11 +770,11 @@ class Inbound_Shortcodes {
 								<?php _e('Form Preview', 'leads'); ?>
 							</div>
 							<?php if( $shortcode->no_preview ) : ?>
 								<div id="inbound-shortcodes-nopreview"><?php _e('Shortcode has no preview', 'leads'); ?></div>
 							<?php else :
-							    if ( isset($_REQUEST['post']) ) {
+							    if ( isset($_REQUEST['post']) && is_int($_REQUEST['post'])  ) {
 								    $post_id = html_entity_decode( $_REQUEST['post'] );
                                 } else {
                                     $post_id = 0;
                                 }
                                 ?>
diff --git a/templates/simple-two-column/assets/css/style.css b/templates/simple-two-column/assets/css/style.css
index 4faafe2..54fb0e6 100644
--- a/templates/simple-two-column/assets/css/style.css
+++ b/templates/simple-two-column/assets/css/style.css
@@ -87,11 +87,11 @@ color: white;
 .lp-span {text-transform: none; display: block; margin-bottom: 8px;}
 .lp-input-label .lp-span {
   display: inline;
   color:red;
 }
-input[type="text"], input[type="email"], #inbound-form-wrapper input[type=text], #inbound-form-wrapper input[type=url], #inbound-form-wrapper input[type=email], #inbound-form-wrapper input[type=tel], #inbound-form-wrapper input[type=number], #inbound-form-wrapper input[type=password] {
+input[type="text"], input[type="email"], #inbound-form-wrapper input[type=text], #inbound-form-wrapper input[type=url], #inbound-form-wrapper input[type=email], #inbound-form-wrapper input[type=tel], #inbound-form-wrapper input[type=number], #inbound-form-wrapper input[type=password] , #inbound-form-wrapper select {
   width: 94%;
 padding: 8px 4px 8px 10px;
 margin-bottom: 15px;
 border: 1px solid #4E3043;
 border: 1px solid rgba(0, 0, 0, 0.8);
diff --git a/tests/build/php.conf b/tests/build/php.conf
new file mode 100644
index 0000000..6e2755c
--- /dev/null
+++ b/tests/build/php.conf
@@ -0,0 +1,4 @@
+<IfModule mod_php5.c>
+  AddType application/x-httpd-php .php .phtml .php5
+  AddType application/x-httpd-php-source .phps
+</IfModule>
\ No newline at end of file
diff --git a/tests/build/php.load b/tests/build/php.load
new file mode 100644
index 0000000..0d6a55e
--- /dev/null
+++ b/tests/build/php.load
@@ -0,0 +1 @@
+LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
\ No newline at end of file
diff --git a/tests/build/scratchpad.sh b/tests/build/scratchpad.sh
new file mode 100644
index 0000000..7dc3491
--- /dev/null
+++ b/tests/build/scratchpad.sh
@@ -0,0 +1 @@
+phantomjs --webdriver=4444
\ No newline at end of file
diff --git a/tests/build/travis-ci-apache b/tests/build/travis-ci-apache
new file mode 100644
index 0000000..d20c9f7
--- /dev/null
+++ b/tests/build/travis-ci-apache
@@ -0,0 +1,23 @@
+<VirtualHost *:80>
+	ServerAdmin tests@inboundnow.com
+	DocumentRoot /var/www/inboundtesting.dev/
+	ServerName inboundtesting.dev
+	ErrorLog ${APACHE_LOG_DIR}/error.log
+    CustomLog ${APACHE_LOG_DIR}/access.log combined
+	
+	# Wire up Apache to use Travis CI's php-fpm.
+	<IfModule mod_fastcgi.c>
+		AddHandler php5-fcgi .php
+		Action php5-fcgi /php5-fcgi
+		Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
+		FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
+	</IfModule>
+  
+	<Directory "/var/www/inboundtesting.dev/">
+		Options FollowSymLinks MultiViews ExecCGI
+		AllowOverride All
+		Order deny,allow
+		Allow from all
+	</Directory>
+</VirtualHost>
+  
\ No newline at end of file
diff --git a/tests/codeception/_bootstrap.php b/tests/codeception/_bootstrap.php
new file mode 100644
index 0000000..e26c07d
--- /dev/null
+++ b/tests/codeception/_bootstrap.php
@@ -0,0 +1,9 @@
+<?php
+
+/* load wp */
+require '../../../wp-load.php';
+require '../../../wp-admin/includes/plugin.php';
+
+/* load required landing pages files */
+include_once LANDINGPAGES_PATH . 'modules/module.install.php';
+include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';
\ No newline at end of file
diff --git a/tests/codeception/_data/dump.sql b/tests/codeception/_data/dump.sql
new file mode 100644
index 0000000..4bc742c
--- /dev/null
+++ b/tests/codeception/_data/dump.sql
@@ -0,0 +1 @@
+/* Replace this file with actual dump of your database */
\ No newline at end of file
diff --git a/tests/codeception/_support/AcceptanceHelper.php b/tests/codeception/_support/AcceptanceHelper.php
new file mode 100644
index 0000000..d09c6e4
--- /dev/null
+++ b/tests/codeception/_support/AcceptanceHelper.php
@@ -0,0 +1,10 @@
+<?php
+namespace Codeception\Module;
+
+// here you can define custom actions
+// all public methods declared in helper class will be available in $I
+
+class AcceptanceHelper extends \Codeception\Module
+{
+
+}
diff --git a/tests/codeception/_support/FunctionalHelper.php b/tests/codeception/_support/FunctionalHelper.php
new file mode 100644
index 0000000..22cc714
--- /dev/null
+++ b/tests/codeception/_support/FunctionalHelper.php
@@ -0,0 +1,10 @@
+<?php
+namespace Codeception\Module;
+
+// here you can define custom actions
+// all public methods declared in helper class will be available in $I
+
+class FunctionalHelper extends \Codeception\Module
+{
+
+}
diff --git a/tests/codeception/_support/UnitHelper.php b/tests/codeception/_support/UnitHelper.php
new file mode 100644
index 0000000..dcbc192
--- /dev/null
+++ b/tests/codeception/_support/UnitHelper.php
@@ -0,0 +1,10 @@
+<?php
+namespace Codeception\Module;
+
+// here you can define custom actions
+// all public methods declared in helper class will be available in $I
+
+class UnitHelper extends \Codeception\Module
+{
+
+}
diff --git a/tests/codeception/acceptance.suite.yml b/tests/codeception/acceptance.suite.yml
new file mode 100644
index 0000000..f1fe862
--- /dev/null
+++ b/tests/codeception/acceptance.suite.yml
@@ -0,0 +1,20 @@
+# Codeception Test Suite Configuration
+
+# suite for acceptance tests.
+# perform tests in browser using the WebDriver or PhpBrowser.
+# If you need both WebDriver and PHPBrowser tests - create a separate suite.
+
+class_name: AcceptanceTester
+modules:
+    enabled:
+        - WebDriver
+        - AcceptanceHelper
+        - Asserts
+    config:
+        WebDriver:
+            url: 'http://local.wordpress.dev/'
+            browser: firefox
+            clear_cookies: false
+            window_size: 1024x768
+        PhpBrowser:
+            url: 'http://inboundsoon.dev'
\ No newline at end of file
diff --git a/tests/codeception/acceptance/AcceptanceTester.php b/tests/codeception/acceptance/AcceptanceTester.php
new file mode 100644
index 0000000..b9460c3
--- /dev/null
+++ b/tests/codeception/acceptance/AcceptanceTester.php
@@ -0,0 +1,1918 @@
+<?php //[STAMP] 2d5aa64986f8f94bc0f812d88aa9dee6
+
+// This class was automatically generated by build task
+// You should not change it manually as it will be overwritten on next build
+// @codingStandardsIgnoreFile
+
+
+use Codeception\Module\PhpBrowser;
+use Codeception\Module\AcceptanceHelper;
+
+/**
+ * Inherited Methods
+ * @method void wantToTest($text)
+ * @method void wantTo($text)
+ * @method void execute($callable)
+ * @method void expectTo($prediction)
+ * @method void expect($prediction)
+ * @method void amGoingTo($argumentation)
+ * @method void am($role)
+ * @method void lookForwardTo($achieveValue)
+ * @method void comment($description)
+ * @method void haveFriend($name, $actorClass = null)
+ *
+ * @SuppressWarnings(PHPMD)
+*/
+class AcceptanceTester extends \Codeception\Actor
+{
+   
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Sets the HTTP header to the passed value - which is used on
+     * subsequent HTTP requests through PhpBrowser.
+     *
+     * Example:
+     * ```php
+     * <?php
+     * $I->setHeader('X-Requested-With', 'Codeception');
+     * $I->amOnPage('test-headers.php');
+     * ?>
+     * ```
+     *
+     * @param string $name the name of the request header
+     * @param string $value the value to set it to for subsequent
+     *        requests
+     * @see \Codeception\Module\PhpBrowser::setHeader()
+     */
+    public function setHeader($name, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('setHeader', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Deletes the header with the passed name.  Subsequent requests
+     * will not have the deleted header in its request.
+     *
+     * Example:
+     * ```php
+     * <?php
+     * $I->setHeader('X-Requested-With', 'Codeception');
+     * $I->amOnPage('test-headers.php');
+     * // ...
+     * $I->deleteHeader('X-Requested-With');
+     * $I->amOnPage('some-other-page.php');
+     * ?>
+     * ```
+     * 
+     * @param string $name the name of the header to delete.
+     * @see \Codeception\Module\PhpBrowser::deleteHeader()
+     */
+    public function deleteHeader($name) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Authenticates user for HTTP_AUTH
+     *
+     * @param $username
+     * @param $password
+     * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated()
+     */
+    public function amHttpAuthenticated($username, $password) {
+        return $this->scenario->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Opens the page for the given relative URI.
+     *
+     * ``` php
+     * <?php
+     * // opens front page
+     * $I->amOnPage('/');
+     * // opens /register page
+     * $I->amOnPage('/register');
+     * ?>
+     * ```
+     *
+     * @param $page
+     * @see \Codeception\Module\PhpBrowser::amOnPage()
+     */
+    public function amOnPage($page) {
+        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Open web page at the given absolute URL and sets its hostname as the base host.
+     *
+     * ``` php
+     * <?php
+     * $I->amOnUrl('http://codeception.com');
+     * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
+     * ?>
+     * ```
+     * @see \Codeception\Module\PhpBrowser::amOnUrl()
+     */
+    public function amOnUrl($url) {
+        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Changes the subdomain for the 'url' configuration parameter.
+     * Does not open a page; use `amOnPage` for that.
+     *
+     * ``` php
+     * <?php
+     * // If config is: 'http://mysite.com'
+     * // or config is: 'http://www.mysite.com'
+     * // or config is: 'http://company.mysite.com'
+     *
+     * $I->amOnSubdomain('user');
+     * $I->amOnPage('/');
+     * // moves to http://user.mysite.com/
+     * ?>
+     * ```
+     *
+     * @param $subdomain
+     *
+     * @return mixed
+     * @see \Codeception\Module\PhpBrowser::amOnSubdomain()
+     */
+    public function amOnSubdomain($subdomain) {
+        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Low-level API method.
+     * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly
+     *
+     * Example:
+     *
+     * ``` php
+     * <?php
+     * $I->executeInGuzzle(function (\GuzzleHttp\Client $client) {
+     *      $client->get('/get', ['query' => ['foo' => 'bar']]);
+     * });
+     * ?>
+     * ```
+     *
+     * It is not recommended to use this command on a regular basis.
+     * If Codeception lacks important Guzzle Client methods, implement them and submit patches.
+     *
+     * @param callable $function
+     * @see \Codeception\Module\PhpBrowser::executeInGuzzle()
+     */
+    public function executeInGuzzle($function) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Perform a click on a link or a button, given by a locator.
+     * If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
+     * For buttons, the "value" attribute, "name" attribute, and inner text are searched.
+     * For links, the link text is searched.
+     * For images, the "alt" attribute and inner text of any parent links are searched.
+     *
+     * The second parameter is a context (CSS or XPath locator) to narrow the search.
+     *
+     * Note that if the locator matches a button of type `submit`, the form will be submitted.
+     *
+     * ``` php
+     * <?php
+     * // simple link
+     * $I->click('Logout');
+     * // button of form
+     * $I->click('Submit');
+     * // CSS button
+     * $I->click('#form input[type=submit]');
+     * // XPath
+     * $I->click('//form/*[@type=submit]');
+     * // link in context
+     * $I->click('Logout', '#nav');
+     * // using strict locator
+     * $I->click(['link' => 'Login']);
+     * ?>
+     * ```
+     *
+     * @param $link
+     * @param $context
+     * @see \Codeception\Lib\InnerBrowser::click()
+     */
+    public function click($link, $context = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('click', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current page contains the given string.
+     * Specify a locator as the second parameter to match a specific region.
+     *
+     * ``` php
+     * <?php
+     * $I->see('Logout'); // I can suppose user is logged in
+     * $I->see('Sign Up','h1'); // I can suppose it's a signup page
+     * $I->see('Sign Up','//body/h1'); // with XPath
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $selector
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::see()
+     */
+    public function canSee($text, $selector = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current page contains the given string.
+     * Specify a locator as the second parameter to match a specific region.
+     *
+     * ``` php
+     * <?php
+     * $I->see('Logout'); // I can suppose user is logged in
+     * $I->see('Sign Up','h1'); // I can suppose it's a signup page
+     * $I->see('Sign Up','//body/h1'); // with XPath
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $selector
+     * @see \Codeception\Lib\InnerBrowser::see()
+     */
+    public function see($text, $selector = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('see', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current page doesn't contain the text specified.
+     * Give a locator as the second parameter to match a specific region.
+     *
+     * ```php
+     * <?php
+     * $I->dontSee('Login'); // I can suppose user is already logged in
+     * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
+     * $I->dontSee('Sign Up','//body/h1'); // with XPath
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $selector
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSee()
+     */
+    public function cantSee($text, $selector = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current page doesn't contain the text specified.
+     * Give a locator as the second parameter to match a specific region.
+     *
+     * ```php
+     * <?php
+     * $I->dontSee('Login'); // I can suppose user is already logged in
+     * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
+     * $I->dontSee('Sign Up','//body/h1'); // with XPath
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $selector
+     * @see \Codeception\Lib\InnerBrowser::dontSee()
+     */
+    public function dontSee($text, $selector = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSee', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there's a link with the specified text.
+     * Give a full URL as the second parameter to match links with that exact URL.
+     *
+     * ``` php
+     * <?php
+     * $I->seeLink('Logout'); // matches <a href="#">Logout</a>
+     * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $url
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeLink()
+     */
+    public function canSeeLink($text, $url = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeLink', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there's a link with the specified text.
+     * Give a full URL as the second parameter to match links with that exact URL.
+     *
+     * ``` php
+     * <?php
+     * $I->seeLink('Logout'); // matches <a href="#">Logout</a>
+     * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
+     * ?>
+     * ```
+     *
+     * @param      $text
+     * @param null $url
+     * @see \Codeception\Lib\InnerBrowser::seeLink()
+     */
+    public function seeLink($text, $url = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeLink', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page doesn't contain a link with the given string.
+     * If the second parameter is given, only links with a matching "href" attribute will be checked.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeLink('Logout'); // I suppose user is not logged in
+     * $I->dontSeeLink('Checkout now', '/store/cart.php');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * @param null $url
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeLink()
+     */
+    public function cantSeeLink($text, $url = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeLink', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page doesn't contain a link with the given string.
+     * If the second parameter is given, only links with a matching "href" attribute will be checked.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeLink('Logout'); // I suppose user is not logged in
+     * $I->dontSeeLink('Checkout now', '/store/cart.php');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * @param null $url
+     * @see \Codeception\Lib\InnerBrowser::dontSeeLink()
+     */
+    public function dontSeeLink($text, $url = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeLink', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that current URI contains the given string.
+     *
+     * ``` php
+     * <?php
+     * // to match: /home/dashboard
+     * $I->seeInCurrentUrl('home');
+     * // to match: /users/1
+     * $I->seeInCurrentUrl('/users/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
+     */
+    public function canSeeInCurrentUrl($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInCurrentUrl', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that current URI contains the given string.
+     *
+     * ``` php
+     * <?php
+     * // to match: /home/dashboard
+     * $I->seeInCurrentUrl('home');
+     * // to match: /users/1
+     * $I->seeInCurrentUrl('/users/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
+     */
+    public function seeInCurrentUrl($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInCurrentUrl', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URI doesn't contain the given string.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeInCurrentUrl('/users/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
+     */
+    public function cantSeeInCurrentUrl($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInCurrentUrl', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URI doesn't contain the given string.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeInCurrentUrl('/users/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
+     */
+    public function dontSeeInCurrentUrl($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInCurrentUrl', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL is equal to the given string.
+     * Unlike `seeInCurrentUrl`, this only matches the full URL.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->seeCurrentUrlEquals('/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
+     */
+    public function canSeeCurrentUrlEquals($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlEquals', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL is equal to the given string.
+     * Unlike `seeInCurrentUrl`, this only matches the full URL.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->seeCurrentUrlEquals('/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
+     */
+    public function seeCurrentUrlEquals($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlEquals', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL doesn't equal the given string.
+     * Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
+     *
+     * ``` php
+     * <?php
+     * // current url is not root
+     * $I->dontSeeCurrentUrlEquals('/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
+     */
+    public function cantSeeCurrentUrlEquals($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlEquals', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL doesn't equal the given string.
+     * Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
+     *
+     * ``` php
+     * <?php
+     * // current url is not root
+     * $I->dontSeeCurrentUrlEquals('/');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
+     */
+    public function dontSeeCurrentUrlEquals($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlEquals', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL matches the given regular expression.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->seeCurrentUrlMatches('~$/users/(\d+)~');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
+     */
+    public function canSeeCurrentUrlMatches($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlMatches', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the current URL matches the given regular expression.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->seeCurrentUrlMatches('~$/users/(\d+)~');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
+     */
+    public function seeCurrentUrlMatches($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlMatches', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that current url doesn't match the given regular expression.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
+     */
+    public function cantSeeCurrentUrlMatches($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlMatches', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that current url doesn't match the given regular expression.
+     *
+     * ``` php
+     * <?php
+     * // to match root url
+     * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
+     * ?>
+     * ```
+     *
+     * @param $uri
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
+     */
+    public function dontSeeCurrentUrlMatches($uri) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlMatches', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Executes the given regular expression against the current URI and returns the first match.
+     * If no parameters are provided, the full URI is returned.
+     *
+     * ``` php
+     * <?php
+     * $user_id = $I->grabFromCurrentUrl('~$/user/(\d+)/~');
+     * $uri = $I->grabFromCurrentUrl();
+     * ?>
+     * ```
+     *
+     * @param null $uri
+     *
+     * @internal param $url
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::grabFromCurrentUrl()
+     */
+    public function grabFromCurrentUrl($uri = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('grabFromCurrentUrl', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the specified checkbox is checked.
+     *
+     * ``` php
+     * <?php
+     * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
+     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
+     * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
+     * ?>
+     * ```
+     *
+     * @param $checkbox
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
+     */
+    public function canSeeCheckboxIsChecked($checkbox) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCheckboxIsChecked', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the specified checkbox is checked.
+     *
+     * ``` php
+     * <?php
+     * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
+     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
+     * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
+     * ?>
+     * ```
+     *
+     * @param $checkbox
+     * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
+     */
+    public function seeCheckboxIsChecked($checkbox) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCheckboxIsChecked', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Check that the specified checkbox is unchecked.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
+     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
+     * ?>
+     * ```
+     *
+     * @param $checkbox
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
+     */
+    public function cantSeeCheckboxIsChecked($checkbox) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCheckboxIsChecked', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Check that the specified checkbox is unchecked.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
+     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
+     * ?>
+     * ```
+     *
+     * @param $checkbox
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
+     */
+    public function dontSeeCheckboxIsChecked($checkbox) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCheckboxIsChecked', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given input field or textarea contains the given value. 
+     * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
+     *
+     * ``` php
+     * <?php
+     * $I->seeInField('Body','Type your comment here');
+     * $I->seeInField('form textarea[name=body]','Type your comment here');
+     * $I->seeInField('form input[type=hidden]','hidden_value');
+     * $I->seeInField('#searchform input','Search');
+     * $I->seeInField('//form/*[@name=search]','Search');
+     * $I->seeInField(['name' => 'search'], 'Search');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $value
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeInField()
+     */
+    public function canSeeInField($field, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInField', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given input field or textarea contains the given value. 
+     * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
+     *
+     * ``` php
+     * <?php
+     * $I->seeInField('Body','Type your comment here');
+     * $I->seeInField('form textarea[name=body]','Type your comment here');
+     * $I->seeInField('form input[type=hidden]','hidden_value');
+     * $I->seeInField('#searchform input','Search');
+     * $I->seeInField('//form/*[@name=search]','Search');
+     * $I->seeInField(['name' => 'search'], 'Search');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $value
+     * @see \Codeception\Lib\InnerBrowser::seeInField()
+     */
+    public function seeInField($field, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInField', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that an input field or textarea doesn't contain the given value.
+     * For fuzzy locators, the field is matched by label text, CSS and XPath.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeInField('Body','Type your comment here');
+     * $I->dontSeeInField('form textarea[name=body]','Type your comment here');
+     * $I->dontSeeInField('form input[type=hidden]','hidden_value');
+     * $I->dontSeeInField('#searchform input','Search');
+     * $I->dontSeeInField('//form/*[@name=search]','Search');
+     * $I->dontSeeInField(['name' => 'search'], 'Search');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $value
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInField()
+     */
+    public function cantSeeInField($field, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInField', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that an input field or textarea doesn't contain the given value.
+     * For fuzzy locators, the field is matched by label text, CSS and XPath.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeInField('Body','Type your comment here');
+     * $I->dontSeeInField('form textarea[name=body]','Type your comment here');
+     * $I->dontSeeInField('form input[type=hidden]','hidden_value');
+     * $I->dontSeeInField('#searchform input','Search');
+     * $I->dontSeeInField('//form/*[@name=search]','Search');
+     * $I->dontSeeInField(['name' => 'search'], 'Search');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $value
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInField()
+     */
+    public function dontSeeInField($field, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInField', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if the array of form parameters (name => value) are set on the form matched with the
+     * passed selector.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('form[name=myform]', [
+     *      'input1' => 'value',
+     *      'input2' => 'other value',
+     * ]);
+     * ?>
+     * ```
+     * 
+     * For multi-select elements, or to check values of multiple elements with the same name, an
+     * array may be passed:
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('.form-class', [
+     *      'multiselect' => [
+     *          'value1',
+     *          'value2',
+     *      ],
+     *      'checkbox[]' => [
+     *          'a checked value',
+     *          'another checked value',
+     *      ],
+     * ]);
+     * ?>
+     * ```
+     *
+     * Additionally, checkbox values can be checked with a boolean.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('#form-id', [
+     *      'checkbox1' => true,        // passes if checked
+     *      'checkbox2' => false,       // passes if unchecked
+     * ]);
+     * ?>
+     * ```
+     * 
+     * Pair this with submitForm for quick testing magic.
+     * 
+     * ``` php
+     * <?php
+     * $form = [
+     *      'field1' => 'value',
+     *      'field2' => 'another value',
+     *      'checkbox1' => true,
+     *      // ...
+     * ];
+     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
+     * // $I->amOnPage('/path/to/form-page') may be needed
+     * $I->seeInFormFields('//form[@id=my-form]', $form);
+     * ?>
+     * ```
+     * 
+     * @param $formSelector
+     * @param $params
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeInFormFields()
+     */
+    public function canSeeInFormFields($formSelector, $params) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInFormFields', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if the array of form parameters (name => value) are set on the form matched with the
+     * passed selector.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('form[name=myform]', [
+     *      'input1' => 'value',
+     *      'input2' => 'other value',
+     * ]);
+     * ?>
+     * ```
+     * 
+     * For multi-select elements, or to check values of multiple elements with the same name, an
+     * array may be passed:
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('.form-class', [
+     *      'multiselect' => [
+     *          'value1',
+     *          'value2',
+     *      ],
+     *      'checkbox[]' => [
+     *          'a checked value',
+     *          'another checked value',
+     *      ],
+     * ]);
+     * ?>
+     * ```
+     *
+     * Additionally, checkbox values can be checked with a boolean.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeInFormFields('#form-id', [
+     *      'checkbox1' => true,        // passes if checked
+     *      'checkbox2' => false,       // passes if unchecked
+     * ]);
+     * ?>
+     * ```
+     * 
+     * Pair this with submitForm for quick testing magic.
+     * 
+     * ``` php
+     * <?php
+     * $form = [
+     *      'field1' => 'value',
+     *      'field2' => 'another value',
+     *      'checkbox1' => true,
+     *      // ...
+     * ];
+     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
+     * // $I->amOnPage('/path/to/form-page') may be needed
+     * $I->seeInFormFields('//form[@id=my-form]', $form);
+     * ?>
+     * ```
+     * 
+     * @param $formSelector
+     * @param $params
+     * @see \Codeception\Lib\InnerBrowser::seeInFormFields()
+     */
+    public function seeInFormFields($formSelector, $params) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInFormFields', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if the array of form parameters (name => value) are not set on the form matched with
+     * the passed selector.
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('form[name=myform]', [
+     *      'input1' => 'non-existent value',
+     *      'input2' => 'other non-existent value',
+     * ]);
+     * ?>
+     * ```
+     * 
+     * To check that an element hasn't been assigned any one of many values, an array can be passed
+     * as the value:
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('.form-class', [
+     *      'fieldName' => [
+     *          'This value shouldn\'t be set',
+     *          'And this value shouldn\'t be set',
+     *      ],
+     * ]);
+     * ?>
+     * ```
+     *
+     * Additionally, checkbox values can be checked with a boolean.
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('#form-id', [
+     *      'checkbox1' => true,        // fails if checked
+     *      'checkbox2' => false,       // fails if unchecked
+     * ]);
+     * ?>
+     * ```
+     * 
+     * @param $formSelector
+     * @param $params
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
+     */
+    public function cantSeeInFormFields($formSelector, $params) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInFormFields', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if the array of form parameters (name => value) are not set on the form matched with
+     * the passed selector.
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('form[name=myform]', [
+     *      'input1' => 'non-existent value',
+     *      'input2' => 'other non-existent value',
+     * ]);
+     * ?>
+     * ```
+     * 
+     * To check that an element hasn't been assigned any one of many values, an array can be passed
+     * as the value:
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('.form-class', [
+     *      'fieldName' => [
+     *          'This value shouldn\'t be set',
+     *          'And this value shouldn\'t be set',
+     *      ],
+     * ]);
+     * ?>
+     * ```
+     *
+     * Additionally, checkbox values can be checked with a boolean.
+     * 
+     * ``` php
+     * <?php
+     * $I->dontSeeInFormFields('#form-id', [
+     *      'checkbox1' => true,        // fails if checked
+     *      'checkbox2' => false,       // fails if unchecked
+     * ]);
+     * ?>
+     * ```
+     * 
+     * @param $formSelector
+     * @param $params
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
+     */
+    public function dontSeeInFormFields($formSelector, $params) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInFormFields', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Submits the given form on the page, optionally with the given form values.
+     * Give the form fields values as an array.
+     *
+     * Skipped fields will be filled by their values from the page.
+     * You don't need to click the 'Submit' button afterwards.
+     * This command itself triggers the request to form's action.
+     *
+     * You can optionally specify what button's value to include
+     * in the request with the last parameter as an alternative to
+     * explicitly setting its value in the second parameter, as
+     * button values are not otherwise included in the request.
+     * 
+     * Examples:
+     *
+     * ``` php
+     * <?php
+     * $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'));
+     * // or
+     * $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'), 'submitButtonName');
+     *
+     * ```
+     *
+     * For example, given this sample "Sign Up" form:
+     *
+     * ``` html
+     * <form action="/sign_up">
+     *     Login: <input type="text" name="user[login]" /><br/>
+     *     Password: <input type="password" name="user[password]" /><br/>
+     *     Do you agree to out terms? <input type="checkbox" name="user[agree]" /><br/>
+     *     Select pricing plan <select name="plan"><option value="1">Free</option><option value="2" selected="selected">Paid</option></select>
+     *     <input type="submit" name="submitButton" value="Submit" />
+     * </form>
+     * ```
+     *
+     * You could write the following to submit it:
+     *
+     * ``` php
+     * <?php
+     * $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)), 'submitButton');
+     *
+     * ```
+     * Note that "2" will be the submitted value for the "plan" field, as it is the selected option.
+     * 
+     * You can also emulate a JavaScript submission by not specifying any buttons in the third parameter to submitForm.
+     * 
+     * ```php
+     * <?php
+     * $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)));
+     * 
+     * ```
+     * 
+     * Pair this with seeInFormFields for quick testing magic.
+     * 
+     * ``` php
+     * <?php
+     * $form = [
+     *      'field1' => 'value',
+     *      'field2' => 'another value',
+     *      'checkbox1' => true,
+     *      // ...
+     * ];
+     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
+     * // $I->amOnPage('/path/to/form-page') may be needed
+     * $I->seeInFormFields('//form[@id=my-form]', $form);
+     * ?>
+     * ```
+     *
+     * Parameter values can be set to arrays for multiple input fields
+     * of the same name, or multi-select combo boxes.  For checkboxes,
+     * either the string value can be used, or boolean values which will
+     * be replaced by the checkbox's value in the DOM.
+     *
+     * ``` php
+     * <?php
+     * $I->submitForm('#my-form', [
+     *      'field1' => 'value',
+     *      'checkbox' => [
+     *          'value of first checkbox',
+     *          'value of second checkbox,
+     *      ],
+     *      'otherCheckboxes' => [
+     *          true,
+     *          false,
+     *          false
+     *      ],
+     *      'multiselect' => [
+     *          'first option value',
+     *          'second option value'
+     *      ]
+     * ]);
+     * ?>
+     * ```
+     *
+     * Mixing string and boolean values for a checkbox's value is not
+     * supported and may produce unexpected results.
+     * 
+     * @param $selector
+     * @param $params
+     * @param $button
+     * @see \Codeception\Lib\InnerBrowser::submitForm()
+     */
+    public function submitForm($selector, $params, $button = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('submitForm', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Fills a text field or textarea with the given string.
+     *
+     * ``` php
+     * <?php
+     * $I->fillField("//input[@type='text']", "Hello World!");
+     * $I->fillField(['name' => 'email'], 'jon@mail.com');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $value
+     * @see \Codeception\Lib\InnerBrowser::fillField()
+     */
+    public function fillField($field, $value) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('fillField', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Selects an option in a select tag or in radio button group.
+     *
+     * ``` php
+     * <?php
+     * $I->selectOption('form select[name=account]', 'Premium');
+     * $I->selectOption('form input[name=payment]', 'Monthly');
+     * $I->selectOption('//form/select[@name=account]', 'Monthly');
+     * ?>
+     * ```
+     *
+     * Provide an array for the second argument to select multiple options:
+     *
+     * ``` php
+     * <?php
+     * $I->selectOption('Which OS do you use?', array('Windows','Linux'));
+     * ?>
+     * ```
+     *
+     * @param $select
+     * @param $option
+     * @see \Codeception\Lib\InnerBrowser::selectOption()
+     */
+    public function selectOption($select, $option) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('selectOption', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
+     *
+     * ``` php
+     * <?php
+     * $I->checkOption('#agree');
+     * ?>
+     * ```
+     *
+     * @param $option
+     * @see \Codeception\Lib\InnerBrowser::checkOption()
+     */
+    public function checkOption($option) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('checkOption', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Unticks a checkbox.
+     *
+     * ``` php
+     * <?php
+     * $I->uncheckOption('#notify');
+     * ?>
+     * ```
+     *
+     * @param $option
+     * @see \Codeception\Lib\InnerBrowser::uncheckOption()
+     */
+    public function uncheckOption($option) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('uncheckOption', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Attaches a file relative to the Codeception data directory to the given file upload field.
+     *
+     * ``` php
+     * <?php
+     * // file is stored in 'tests/_data/prices.xls'
+     * $I->attachFile('input[@type="file"]', 'prices.xls');
+     * ?>
+     * ```
+     *
+     * @param $field
+     * @param $filename
+     * @see \Codeception\Lib\InnerBrowser::attachFile()
+     */
+    public function attachFile($field, $filename) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('attachFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * If your page triggers an ajax request, you can perform it manually.
+     * This action sends a GET ajax request with specified params.
+     *
+     * See ->sendAjaxPostRequest for examples.
+     *
+     * @param $uri
+     * @param $params
+     * @see \Codeception\Lib\InnerBrowser::sendAjaxGetRequest()
+     */
+    public function sendAjaxGetRequest($uri, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxGetRequest', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * If your page triggers an ajax request, you can perform it manually.
+     * This action sends a POST ajax request with specified params.
+     * Additional params can be passed as array.
+     *
+     * Example:
+     *
+     * Imagine that by clicking checkbox you trigger ajax request which updates user settings.
+     * We emulate that click by running this ajax request manually.
+     *
+     * ``` php
+     * <?php
+     * $I->sendAjaxPostRequest('/updateSettings', array('notifications' => true)); // POST
+     * $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GET
+     *
+     * ```
+     *
+     * @param $uri
+     * @param $params
+     * @see \Codeception\Lib\InnerBrowser::sendAjaxPostRequest()
+     */
+    public function sendAjaxPostRequest($uri, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxPostRequest', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * If your page triggers an ajax request, you can perform it manually.
+     * This action sends an ajax request with specified method and params.
+     *
+     * Example:
+     *
+     * You need to perform an ajax request specifying the HTTP method.
+     *
+     * ``` php
+     * <?php
+     * $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
+     *
+     * ```
+     *
+     * @param $method
+     * @param $uri
+     * @param $params
+     * @see \Codeception\Lib\InnerBrowser::sendAjaxRequest()
+     */
+    public function sendAjaxRequest($method, $uri, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxRequest', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Finds and returns the text contents of the given element.
+     * If a fuzzy locator is used, the element is found using CSS, XPath, and by matching the full page source by regular expression.
+     *
+     * ``` php
+     * <?php
+     * $heading = $I->grabTextFrom('h1');
+     * $heading = $I->grabTextFrom('descendant-or-self::h1');
+     * $value = $I->grabTextFrom('~<input value=(.*?)]~sgi'); // match with a regex
+     * ?>
+     * ```
+     *
+     * @param $cssOrXPathOrRegex
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::grabTextFrom()
+     */
+    public function grabTextFrom($cssOrXPathOrRegex) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('grabTextFrom', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Grabs the value of the given attribute value from the given element.
+     * Fails if element is not found.
+     *
+     * ``` php
+     * <?php
+     * $I->grabAttributeFrom('#tooltip', 'title');
+     * ?>
+     * ```
+     *
+     *
+     * @param $cssOrXpath
+     * @param $attribute
+     * @internal param $element
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::grabAttributeFrom()
+     */
+    public function grabAttributeFrom($cssOrXpath, $attribute) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('grabAttributeFrom', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * @param $field
+     *
+     * @return array|mixed|null|string
+     * @see \Codeception\Lib\InnerBrowser::grabValueFrom()
+     */
+    public function grabValueFrom($field) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('grabValueFrom', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Sets a cookie with the given name and value.
+     * You can set additional cookie params like `domain`, `path`, `expire`, `secure` in array passed as last argument.
+     *
+     * ``` php
+     * <?php
+     * $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
+     * ?>
+     * ```
+     *
+     * @param $name
+     * @param $val
+     * @param array $params
+     * @internal param $cookie
+     * @internal param $value
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::setCookie()
+     */
+    public function setCookie($name, $val, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('setCookie', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Grabs a cookie value.
+     * You can set additional cookie params like `domain`, `path` in array passed as last argument.
+     *
+     * @param $cookie
+     *
+     * @param array $params
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::grabCookie()
+     */
+    public function grabCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('grabCookie', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that a cookie with the given name is set.
+     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
+     *
+     * ``` php
+     * <?php
+     * $I->seeCookie('PHPSESSID');
+     * ?>
+     * ```
+     *
+     * @param $cookie
+     * @param array $params
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeCookie()
+     */
+    public function canSeeCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that a cookie with the given name is set.
+     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
+     *
+     * ``` php
+     * <?php
+     * $I->seeCookie('PHPSESSID');
+     * ?>
+     * ```
+     *
+     * @param $cookie
+     * @param array $params
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::seeCookie()
+     */
+    public function seeCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there isn't a cookie with the given name.
+     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
+     *
+     * @param $cookie
+     *
+     * @param array $params
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
+     */
+    public function cantSeeCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there isn't a cookie with the given name.
+     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
+     *
+     * @param $cookie
+     *
+     * @param array $params
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
+     */
+    public function dontSeeCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCookie', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Unsets cookie with the given name.
+     * You can set additional cookie params like `domain`, `path` in array passed as last argument.
+     *
+     * @param $cookie
+     *
+     * @param array $params
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::resetCookie()
+     */
+    public function resetCookie($name, $params = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('resetCookie', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given element exists on the page and is visible.
+     * You can also specify expected attributes of this element.
+     *
+     * ``` php
+     * <?php
+     * $I->seeElement('.error');
+     * $I->seeElement('//form/input[1]');
+     * $I->seeElement('input', ['name' => 'login']);
+     * $I->seeElement('input', ['value' => '123456']);
+     *
+     * // strict locator in first arg, attributes in second
+     * $I->seeElement(['css' => 'form input'], ['name' => 'login']);
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param array $attributes
+     * @return
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeElement()
+     */
+    public function canSeeElement($selector, $attributes = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeElement', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given element exists on the page and is visible.
+     * You can also specify expected attributes of this element.
+     *
+     * ``` php
+     * <?php
+     * $I->seeElement('.error');
+     * $I->seeElement('//form/input[1]');
+     * $I->seeElement('input', ['name' => 'login']);
+     * $I->seeElement('input', ['value' => '123456']);
+     *
+     * // strict locator in first arg, attributes in second
+     * $I->seeElement(['css' => 'form input'], ['name' => 'login']);
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param array $attributes
+     * @return
+     * @see \Codeception\Lib\InnerBrowser::seeElement()
+     */
+    public function seeElement($selector, $attributes = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeElement', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given element is invisible or not present on the page.
+     * You can also specify expected attributes of this element.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeElement('.error');
+     * $I->dontSeeElement('//form/input[1]');
+     * $I->dontSeeElement('input', ['name' => 'login']);
+     * $I->dontSeeElement('input', ['value' => '123456']);
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param array $attributes
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeElement()
+     */
+    public function cantSeeElement($selector, $attributes = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeElement', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given element is invisible or not present on the page.
+     * You can also specify expected attributes of this element.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeElement('.error');
+     * $I->dontSeeElement('//form/input[1]');
+     * $I->dontSeeElement('input', ['name' => 'login']);
+     * $I->dontSeeElement('input', ['value' => '123456']);
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param array $attributes
+     * @see \Codeception\Lib\InnerBrowser::dontSeeElement()
+     */
+    public function dontSeeElement($selector, $attributes = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeElement', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there are a certain number of elements matched by the given locator on the page.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeNumberOfElements('tr', 10);
+     * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
+     * ?>
+     * ```
+     * @param $selector
+     * @param mixed $expected:
+     * - string: strict number
+     * - array: range of numbers [0,10]
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
+     */
+    public function canSeeNumberOfElements($selector, $expected) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElements', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that there are a certain number of elements matched by the given locator on the page.
+     * 
+     * ``` php
+     * <?php
+     * $I->seeNumberOfElements('tr', 10);
+     * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
+     * ?>
+     * ```
+     * @param $selector
+     * @param mixed $expected:
+     * - string: strict number
+     * - array: range of numbers [0,10]
+     * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
+     */
+    public function seeNumberOfElements($selector, $expected) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeNumberOfElements', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given option is selected.
+     *
+     * ``` php
+     * <?php
+     * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param $optionText
+     *
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
+     */
+    public function canSeeOptionIsSelected($select, $optionText) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeOptionIsSelected', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given option is selected.
+     *
+     * ``` php
+     * <?php
+     * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param $optionText
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
+     */
+    public function seeOptionIsSelected($select, $optionText) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeOptionIsSelected', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given option is not selected.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param $optionText
+     *
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
+     */
+    public function cantSeeOptionIsSelected($select, $optionText) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeOptionIsSelected', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the given option is not selected.
+     *
+     * ``` php
+     * <?php
+     * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
+     * ?>
+     * ```
+     *
+     * @param $selector
+     * @param $optionText
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
+     */
+    public function dontSeeOptionIsSelected($select, $optionText) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeOptionIsSelected', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Asserts that current page has 404 response status code.
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seePageNotFound()
+     */
+    public function canSeePageNotFound() {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seePageNotFound', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Asserts that current page has 404 response status code.
+     * @see \Codeception\Lib\InnerBrowser::seePageNotFound()
+     */
+    public function seePageNotFound() {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seePageNotFound', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that response code is equal to value provided.
+     *
+     * @param $code
+     *
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
+     */
+    public function canSeeResponseCodeIs($code) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that response code is equal to value provided.
+     *
+     * @param $code
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
+     */
+    public function seeResponseCodeIs($code) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page title contains the given string.
+     *
+     * ``` php
+     * <?php
+     * $I->seeInTitle('Blog - Post #1');
+     * ?>
+     * ```
+     *
+     * @param $title
+     *
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::seeInTitle()
+     */
+    public function canSeeInTitle($title) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInTitle', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page title contains the given string.
+     *
+     * ``` php
+     * <?php
+     * $I->seeInTitle('Blog - Post #1');
+     * ?>
+     * ```
+     *
+     * @param $title
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::seeInTitle()
+     */
+    public function seeInTitle($title) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInTitle', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page title does not contain the given string.
+     *
+     * @param $title
+     *
+     * @return mixed
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
+     */
+    public function cantSeeInTitle($title) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInTitle', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that the page title does not contain the given string.
+     *
+     * @param $title
+     *
+     * @return mixed
+     * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
+     */
+    public function dontSeeInTitle($title) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInTitle', func_get_args()));
+    }
+}
diff --git a/tests/codeception/acceptance/LoginCept.php b/tests/codeception/acceptance/LoginCept.php
new file mode 100644
index 0000000..41b51a8
--- /dev/null
+++ b/tests/codeception/acceptance/LoginCept.php
@@ -0,0 +1,8 @@
+<?php
+$I = new AcceptanceTester($scenario);
+$I->wantTo('login to wp-admin');
+$I->amOnPage( site_url().'/wp-login.php' );
+$I->fillField('Username', 'admin');
+$I->fillField('Password','admin');
+$I->click('Log In');
+$I->see('Dashboard');
diff --git a/tests/codeception/acceptance/StatisticsCept.php b/tests/codeception/acceptance/StatisticsCept.php
new file mode 100644
index 0000000..572661e
--- /dev/null
+++ b/tests/codeception/acceptance/StatisticsCept.php
@@ -0,0 +1,55 @@
+<?php 
+
+/**
+*  This test is desnged to test the impressions/conversions systems of landing pages.
+*  Systems tested:
+*   -  Dmummy landing page creation
+*   -  Impression/Conversion UI display on landing page edit screen
+*   -  Cear individual landing page stats buttons.
+*   -  Manually setting impressions/conversions
+*   -  Makes sure landing page does not 404
+*   -  Frontend impression ajax systems
+*   -  Variation rotation systems
+*   -  Conversion tracking system for inbount form
+*   -  Conversion tracking system for tracked link
+*/
+
+/* create test landing page */
+$lp_id = inbound_install_example_lander();
+shell_exec('here');
+shell_exec($lp_id);
+$permalink = get_post_permalink( $lp_id , false ); 
+shell_exec($permalink);
+$I = new AcceptanceTester($scenario);
+
+
+$I->wantTo('check example landing page is editable');
+$I->amOnPage( admin_url( 'post.php?post='. $lp_id .'&action=edit&frontend=false') );
+$I->seeInField( '#title','A/B Testing Landing Page Example');
+
+$I->wantTo('check if impressions are correct for variation a');
+$imp = $I->grabTextFrom('#lp-variation-A .bab-stat-span-impressions');
+$I->assertContains( '30' , $imp );
+
+$I->wantTo('check check impressions for variation b');
+$imp = $I->grabTextFrom('#lp-variation-B .bab-stat-span-impressions');
+$I->assertContains( '35' , $imp , ''  );
+
+$I->wantTo('check conversions for variation a');
+$con = $I->grabTextFrom('#lp-variation-A .bab-stat-span-conversions');
+$I->assertContains( '10' , $con , '' );
+
+$I->wantTo('check conversions for variation b');
+$con = $I->grabTextFrom('#lp-variation-B .bab-stat-span-conversions');
+$I->assertContains( '15' , $con  );
+
+$I->wantTo('check the conversion rate of variation a');
+$per = $I->grabTextFrom('#lp-variation-A .bab-stat-span-conversion_rate');
+$I->assertContains( '33' , $per  );
+
+$I->wantTo('check the conversion rate of variation b');
+$per = $I->grabTextFrom('#lp-variation-B .bab-stat-span-conversion_rate');
+$I->assertContains( '43' , $per  );
+
+
+
diff --git a/tests/codeception/acceptance/WelcomeCept.php b/tests/codeception/acceptance/WelcomeCept.php
new file mode 100644
index 0000000..3555a9f
--- /dev/null
+++ b/tests/codeception/acceptance/WelcomeCept.php
@@ -0,0 +1,7 @@
+<?php 
+
+$I = new AcceptanceTester($scenario);
+$I->wantTo('Make sure the default WordPress homepage loads.');
+$I->amOnPage( site_url() );
+$I->see('Hello world!');
+
diff --git a/tests/codeception/acceptance/_bootstrap.php b/tests/codeception/acceptance/_bootstrap.php
new file mode 100644
index 0000000..8a88555
--- /dev/null
+++ b/tests/codeception/acceptance/_bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+// Here you can initialize variables that will be available to your tests
diff --git a/tests/codeception/functional.suite.yml b/tests/codeception/functional.suite.yml
new file mode 100644
index 0000000..3b17a39
--- /dev/null
+++ b/tests/codeception/functional.suite.yml
@@ -0,0 +1,9 @@
+# Codeception Test Suite Configuration
+
+# suite for functional (integration) tests.
+# emulate web requests and make application process them.
+# Include one of framework modules (Symfony2, Yii2, Laravel4) to use it.
+
+class_name: FunctionalTester
+modules:
+    enabled: [Filesystem, FunctionalHelper]
diff --git a/tests/codeception/functional/FunctionalTester.php b/tests/codeception/functional/FunctionalTester.php
new file mode 100644
index 0000000..838eda4
--- /dev/null
+++ b/tests/codeception/functional/FunctionalTester.php
@@ -0,0 +1,360 @@
+<?php //[STAMP] fa259e6277a310881c0cdeb89563ce4c
+
+// This class was automatically generated by build task
+// You should not change it manually as it will be overwritten on next build
+// @codingStandardsIgnoreFile
+
+
+use Codeception\Module\Filesystem;
+use Codeception\Module\FunctionalHelper;
+
+/**
+ * Inherited Methods
+ * @method void wantToTest($text)
+ * @method void wantTo($text)
+ * @method void execute($callable)
+ * @method void expectTo($prediction)
+ * @method void expect($prediction)
+ * @method void amGoingTo($argumentation)
+ * @method void am($role)
+ * @method void lookForwardTo($achieveValue)
+ * @method void comment($description)
+ * @method void haveFriend($name, $actorClass = null)
+ *
+ * @SuppressWarnings(PHPMD)
+*/
+class FunctionalTester extends \Codeception\Actor
+{
+   
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Enters a directory In local filesystem.
+     * Project root directory is used by default
+     *
+     * @param $path
+     * @see \Codeception\Module\Filesystem::amInPath()
+     */
+    public function amInPath($path) {
+        return $this->scenario->runStep(new \Codeception\Step\Condition('amInPath', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Opens a file and stores it's content.
+     *
+     * Usage:
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('composer.json');
+     * $I->seeInThisFile('codeception/codeception');
+     * ?>
+     * ```
+     *
+     * @param $filename
+     * @see \Codeception\Module\Filesystem::openFile()
+     */
+    public function openFile($filename) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('openFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Deletes a file
+     *
+     * ``` php
+     * <?php
+     * $I->deleteFile('composer.lock');
+     * ?>
+     * ```
+     *
+     * @param $filename
+     * @see \Codeception\Module\Filesystem::deleteFile()
+     */
+    public function deleteFile($filename) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('deleteFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Deletes directory with all subdirectories
+     *
+     * ``` php
+     * <?php
+     * $I->deleteDir('vendor');
+     * ?>
+     * ```
+     *
+     * @param $dirname
+     * @see \Codeception\Module\Filesystem::deleteDir()
+     */
+    public function deleteDir($dirname) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('deleteDir', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Copies directory with all contents
+     *
+     * ``` php
+     * <?php
+     * $I->copyDir('vendor','old_vendor');
+     * ?>
+     * ```
+     *
+     * @param $src
+     * @param $dst
+     * @see \Codeception\Module\Filesystem::copyDir()
+     */
+    public function copyDir($src, $dst) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('copyDir', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks If opened file has `text` in it.
+     *
+     * Usage:
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('composer.json');
+     * $I->seeInThisFile('codeception/codeception');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Module\Filesystem::seeInThisFile()
+     */
+    public function canSeeInThisFile($text) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInThisFile', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks If opened file has `text` in it.
+     *
+     * Usage:
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('composer.json');
+     * $I->seeInThisFile('codeception/codeception');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * @see \Codeception\Module\Filesystem::seeInThisFile()
+     */
+    public function seeInThisFile($text) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInThisFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks the strict matching of file contents.
+     * Unlike `seeInThisFile` will fail if file has something more than expected lines.
+     * Better to use with HEREDOC strings.
+     * Matching is done after removing "\r" chars from file content.
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('process.pid');
+     * $I->seeFileContentsEqual('3192');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Module\Filesystem::seeFileContentsEqual()
+     */
+    public function canSeeFileContentsEqual($text) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileContentsEqual', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks the strict matching of file contents.
+     * Unlike `seeInThisFile` will fail if file has something more than expected lines.
+     * Better to use with HEREDOC strings.
+     * Matching is done after removing "\r" chars from file content.
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('process.pid');
+     * $I->seeFileContentsEqual('3192');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * @see \Codeception\Module\Filesystem::seeFileContentsEqual()
+     */
+    public function seeFileContentsEqual($text) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileContentsEqual', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks If opened file doesn't contain `text` in it
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('composer.json');
+     * $I->dontSeeInThisFile('codeception/codeception');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Module\Filesystem::dontSeeInThisFile()
+     */
+    public function cantSeeInThisFile($text) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInThisFile', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks If opened file doesn't contain `text` in it
+     *
+     * ``` php
+     * <?php
+     * $I->openFile('composer.json');
+     * $I->dontSeeInThisFile('codeception/codeception');
+     * ?>
+     * ```
+     *
+     * @param $text
+     * @see \Codeception\Module\Filesystem::dontSeeInThisFile()
+     */
+    public function dontSeeInThisFile($text) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInThisFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Deletes a file
+     * @see \Codeception\Module\Filesystem::deleteThisFile()
+     */
+    public function deleteThisFile() {
+        return $this->scenario->runStep(new \Codeception\Step\Action('deleteThisFile', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if file exists in path.
+     * Opens a file when it's exists
+     *
+     * ``` php
+     * <?php
+     * $I->seeFileFound('UserModel.php','app/models');
+     * ?>
+     * ```
+     *
+     * @param $filename
+     * @param string $path
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Module\Filesystem::seeFileFound()
+     */
+    public function canSeeFileFound($filename, $path = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileFound', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if file exists in path.
+     * Opens a file when it's exists
+     *
+     * ``` php
+     * <?php
+     * $I->seeFileFound('UserModel.php','app/models');
+     * ?>
+     * ```
+     *
+     * @param $filename
+     * @param string $path
+     * @see \Codeception\Module\Filesystem::seeFileFound()
+     */
+    public function seeFileFound($filename, $path = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileFound', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if file does not exists in path
+     *
+     * @param $filename
+     * @param string $path
+     * Conditional Assertion: Test won't be stopped on fail
+     * @see \Codeception\Module\Filesystem::dontSeeFileFound()
+     */
+    public function cantSeeFileFound($filename, $path = null) {
+        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeFileFound', func_get_args()));
+    }
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks if file does not exists in path
+     *
+     * @param $filename
+     * @param string $path
+     * @see \Codeception\Module\Filesystem::dontSeeFileFound()
+     */
+    public function dontSeeFileFound($filename, $path = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeFileFound', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Erases directory contents
+     *
+     * ``` php
+     * <?php
+     * $I->cleanDir('logs');
+     * ?>
+     * ```
+     *
+     * @param $dirname
+     * @see \Codeception\Module\Filesystem::cleanDir()
+     */
+    public function cleanDir($dirname) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('cleanDir', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Saves contents to file
+     *
+     * @param $filename
+     * @param $contents
+     * @see \Codeception\Module\Filesystem::writeToFile()
+     */
+    public function writeToFile($filename, $contents) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('writeToFile', func_get_args()));
+    }
+}
diff --git a/tests/codeception/functional/_bootstrap.php b/tests/codeception/functional/_bootstrap.php
new file mode 100644
index 0000000..8a88555
--- /dev/null
+++ b/tests/codeception/functional/_bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+// Here you can initialize variables that will be available to your tests
diff --git a/tests/codeception/unit.suite.yml b/tests/codeception/unit.suite.yml
new file mode 100644
index 0000000..4ffbf16
--- /dev/null
+++ b/tests/codeception/unit.suite.yml
@@ -0,0 +1,6 @@
+# Codeception Test Suite Configuration
+
+# suite for unit (internal) tests.
+class_name: UnitTester
+modules:
+    enabled: [Asserts, UnitHelper]
diff --git a/tests/codeception/unit/UnitTester.php b/tests/codeception/unit/UnitTester.php
new file mode 100644
index 0000000..f391a58
--- /dev/null
+++ b/tests/codeception/unit/UnitTester.php
@@ -0,0 +1,300 @@
+<?php //[STAMP] c8568e8eab4a240544c36ae031f88bd8
+
+// This class was automatically generated by build task
+// You should not change it manually as it will be overwritten on next build
+// @codingStandardsIgnoreFile
+
+
+use Codeception\Module\Asserts;
+use Codeception\Module\UnitHelper;
+
+/**
+ * Inherited Methods
+ * @method void wantToTest($text)
+ * @method void wantTo($text)
+ * @method void execute($callable)
+ * @method void expectTo($prediction)
+ * @method void expect($prediction)
+ * @method void amGoingTo($argumentation)
+ * @method void am($role)
+ * @method void lookForwardTo($achieveValue)
+ * @method void comment($description)
+ * @method void haveFriend($name, $actorClass = null)
+ *
+ * @SuppressWarnings(PHPMD)
+*/
+class UnitTester extends \Codeception\Actor
+{
+   
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that two variables are equal.
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     *
+     * @return mixed
+     * @see \Codeception\Module\Asserts::assertEquals()
+     */
+    public function assertEquals($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertEquals', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that two variables are not equal
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNotEquals()
+     */
+    public function assertNotEquals($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that two variables are same
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     *
+     * @return mixed
+     * @see \Codeception\Module\Asserts::assertSame()
+     */
+    public function assertSame($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertSame', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that two variables are not same
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNotSame()
+     */
+    public function assertNotSame($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that expected is greater than actual
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertGreaterThan()
+     */
+    public function assertGreaterThan($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * @deprecated
+     * @see \Codeception\Module\Asserts::assertGreaterThen()
+     */
+    public function assertGreaterThen($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that expected is greater or equal than actual
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertGreaterThanOrEqual()
+     */
+    public function assertGreaterThanOrEqual($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * @deprecated
+     * @see \Codeception\Module\Asserts::assertGreaterThenOrEqual()
+     */
+    public function assertGreaterThenOrEqual($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that expected is less than actual
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertLessThan()
+     */
+    public function assertLessThan($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that expected is less or equal than actual
+     *
+     * @param        $expected
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertLessThanOrEqual()
+     */
+    public function assertLessThanOrEqual($expected, $actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that haystack contains needle
+     *
+     * @param        $needle
+     * @param        $haystack
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertContains()
+     */
+    public function assertContains($needle, $haystack, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertContains', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that haystack doesn't contain needle.
+     *
+     * @param        $needle
+     * @param        $haystack
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNotContains()
+     */
+    public function assertNotContains($needle, $haystack, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that variable is empty.
+     *
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertEmpty()
+     */
+    public function assertEmpty($actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that variable is not empty.
+     *
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNotEmpty()
+     */
+    public function assertNotEmpty($actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that variable is NULL
+     *
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNull()
+     */
+    public function assertNull($actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNull', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that variable is not NULL
+     *
+     * @param        $actual
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertNotNull()
+     */
+    public function assertNotNull($actual, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that condition is positive.
+     *
+     * @param        $condition
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertTrue()
+     */
+    public function assertTrue($condition, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertTrue', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Checks that condition is negative.
+     *
+     * @param        $condition
+     * @param string $message
+     * @see \Codeception\Module\Asserts::assertFalse()
+     */
+    public function assertFalse($condition, $message = null) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('assertFalse', func_get_args()));
+    }
+
+ 
+    /**
+     * [!] Method is generated. Documentation taken from corresponding module.
+     *
+     * Fails the test with message.
+     *
+     * @param $message
+     * @see \Codeception\Module\Asserts::fail()
+     */
+    public function fail($message) {
+        return $this->scenario->runStep(new \Codeception\Step\Action('fail', func_get_args()));
+    }
+}
diff --git a/tests/codeception/unit/_bootstrap.php b/tests/codeception/unit/_bootstrap.php
new file mode 100644
index 0000000..8a88555
--- /dev/null
+++ b/tests/codeception/unit/_bootstrap.php
@@ -0,0 +1,2 @@
+<?php
+// Here you can initialize variables that will be available to your tests
diff --git a/tests/phantomjs/server.js b/tests/phantomjs/server.js
new file mode 100644
index 0000000..734f907
--- /dev/null
+++ b/tests/phantomjs/server.js
@@ -0,0 +1,82 @@
+/**
+ *  PhantomJs server for calling webpages & processing JS
+ *  returns page content
+ */
+
+var args = require('system').args;
+var address = args[1];
+var page = new WebPage();
+
+var renderPage = function(){
+
+    page = require('webpage').create();
+    var myArgs = Array.prototype.slice.call(arguments),
+        url_str = myArgs[0];
+
+	 console.log('accessing:'+url_str);
+	
+	page.onError = function(msg){console.log('js error');}
+	
+    /**
+     * From PhantomJS documentation:
+     * This callback is invoked when there is a JavaScript console. The callback may accept up to three arguments:
+     * the string for the message, the line number, and the source identifier.
+     */
+    page.onConsoleMessage = function (msg, line, source) {
+        console.log('console> ' + msg);
+    };
+
+    /**
+     * From PhantomJS documentation:
+     * This callback is invoked when there is a JavaScript alert. The only argument passed to the callback is the string for the message.
+     */
+    page.onAlert = function (msg) {
+        console.log('alert!!> ' + msg);
+    };
+
+    /**
+     * Handle Redirection
+     */
+    page.onNavigationRequested = function(url_sub_str, type, willNavigate, main) {
+        if (main && url_sub_str != url_str) {
+            url_str = url_sub_str;
+            console.log("redirect caught");
+            page.close();
+            setTimeout(function() {
+				renderPage(url_str)
+			},1);
+        }
+    };
+	
+	page.onResourceReceived = function (response) {
+		//console.log('Receive ' + JSON.stringify(response, undefined, 4));
+	};
+	
+	//page.onLoadFinished = function() { console.log(&quot;onLoadFinished FIRED&quot;); }
+
+    /**
+     * Open the web page and run RRunner
+     */
+    page.open(url_str, function(status) {
+		console.log('here');
+        if (status === 'success') {
+            console.log(page.content); 
+			page.close();
+			setTimeout( function() {
+				
+				phantom.exit();
+			} , 5000);
+        } else {
+            console.log('failed');			
+            phantom.exit();
+        }
+    });
+};
+
+
+address = 'http://local.wordpress.dev/test.php';
+//address = 'http://local.wordpress.dev/';
+//address = 'http://www.simpleweb.org/';
+renderPage(address);
+
+
diff --git a/tests/phantomjs/server.php b/tests/phantomjs/server.php
new file mode 100644
index 0000000..4a17a39
--- /dev/null
+++ b/tests/phantomjs/server.php
@@ -0,0 +1,10 @@
+<?php
+//echo shell_exec( '/usr/bin/phantomjs /vagrant/www/wordpress-default/wp-content/plugins/landing-pages/tests/phantomjs/server.js' );
+//sleep(10);
+
+//$output = shell_exec('/usr/bin/phantomjs server.js');
+//echo "<pre>$output</pre>";
+error_reporting(E_ALL);
+session_write_close();
+$result = shell_exec('phantomjs  --web-security=false --ssl-protocol=any server.js ' . $_GET['url'] ); 
+echo $result;
\ No newline at end of file
diff --git a/tests/phantomjs/server.sh b/tests/phantomjs/server.sh
new file mode 100644
index 0000000..8507c8a
--- /dev/null
+++ b/tests/phantomjs/server.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+export DISPLAY=:0
+phantomjs --ignore-ssl-errors=true server.js  2>&1
\ No newline at end of file
diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php
new file mode 100644
index 0000000..e2c2019
--- /dev/null
+++ b/tests/phpunit/bootstrap.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Bootstrap the plugin unit testing environment.
+ *
+ * @package wordpress-plugin-tests
+ */
+
+/* load wp environemnt */
+require '../../../wp-load.php';
+
+/* load plugins */
+require '../../../wp-admin/includes/plugin.php';
+
+/**
+*  Replacement for wp_remote_get
+*  processes javascript through PhantomJs
+*/
+function inbound_remote_get( $url ) {
+	$response = wp_remote_get( 
+		add_query_arg( 
+			array( 'url' => urlencode( $url ) ) , 
+			LANDINGPAGES_URLPATH . 'tests/phantomjs/server.php'
+		) 
+	);
+	
+	return $response;	
+} 
+
+
+
diff --git a/tests/phpunit/test.activations.php b/tests/phpunit/test.activations.php
new file mode 100644
index 0000000..22d287b
--- /dev/null
+++ b/tests/phpunit/test.activations.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Tests to test that that testing framework is testing tests. Meta, huh?
+ *
+ * @package wordpress-plugins-tests
+ */
+class Tests_Activation extends PHPUnit_Framework_TestCase {
+
+	/**
+	* Run a simple test to ensure that the tests are running
+	*/
+	function test_tests() {
+		$this->assertTrue( true );
+	}
+
+	/**
+	* Ensure landing pages is active
+	*/
+	function test_lading_pages_activated() {
+		$this->assertTrue( is_plugin_active( 'landing-pages/landing-pages.php' ) );
+	}
+
+	/**
+	* Ensure that the Leads has been installed and activated.
+	*/
+	function test_leads_activated() {
+		$this->assertTrue( is_plugin_active( 'leads/leads.php' ) );
+	}
+
+	/**
+	* Ensure that the Calls to Action has been installed and activated.
+	*/
+	function test_cta_activated() {
+		$this->assertTrue( is_plugin_active( 'cta/calls-to-action.php' ) );
+	}
+
+	/**
+	* Run upgrade routines and check option to see if complete
+	*/
+	function test_run_upgrade_routines() {
+		include_once LANDINGPAGES_PATH . 'classes/class.activation.php';
+		include_once LANDINGPAGES_PATH . 'classes/class.activation.upgrade-routines.php';
+		Landing_Pages_Activation::run_updates();
+		$this->assertTrue( true );
+	}
+
+}
+
+?>
diff --git a/tests/phpunit/test.statistics.php b/tests/phpunit/test.statistics.php
new file mode 100644
index 0000000..42563fc
--- /dev/null
+++ b/tests/phpunit/test.statistics.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * Test design to juse phantomjs to interact with front end. This test is disabled in favor for codeception tests
+ *
+ * @package wordpress-plugins-tests
+ */
+class Tests_Statistics extends PHPUnit_Framework_TestCase {
+
+    var $lp_id;
+    var $variations;
+
+    /**
+     * setup
+     */
+    function setUp() {
+		return;
+        /* includes */
+        include_once LANDINGPAGES_PATH . 'modules/module.install.php';
+        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';
+
+        $this->lp_id = inbound_install_example_lander();
+        /*  clear the stats */
+        $this->variations = Landing_Pages_Statistics::get_variations($this->lp_id );
+        foreach ($this->variations as $vid) {
+            Landing_Pages_Statistics::set_impression_count( $this->lp_id , $vid, 0 );
+            Landing_Pages_Statistics::set_conversion_count( $this->lp_id , $vid, 0 );
+        }		
+    }
+
+	/**
+	*  Tear down
+	*/
+	function tearDown() {	
+		return;
+		//delete_option('lp_settings_general');
+		//wp_delete_post( $this->lp_id , false );
+	}
+	
+	
+    /**
+     * Test is Landing_Pages_Statistics::read_statistics works
+     */
+    function test_read_statistics() {
+		return;
+		
+        /* includes */
+        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';
+
+        $stats = Landing_Pages_Statistics::read_statistics( $this->lp_id );
+
+        $this->assertEquals( count($stats) , 3 );
+        $this->assertEquals( $stats['impressions'][0] , 0 );
+        $this->assertEquals( $stats['conversions'][0] , 0 );
+        $this->assertEquals( $stats['impressions'][1] , 0 );
+        $this->assertEquals( $stats['conversions'][1] , 0 );
+    }
+
+    /**
+     * launch a landing page
+     */
+    function test_landing_page_read() {
+		return;
+		
+        /* includes */
+        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';
+
+        $permalink = get_post_permalink( $this->lp_id , false ); 
+		echo $permalink."\r\n";	
+		$permalink = 'http://local.wordpress.dev/go/ab-testing-landing-page-example-104/?lp-variation-id=1';
+		$permalink = 'http://local.wordpress.dev/';
+        print_r(inbound_remote_get( $permalink ));   
+		/*
+		sleep(5);
+        $response = inbound_remote_get( $permalink );
+		sleep(5);
+        $response = inbound_remote_get( $permalink );
+		sleep(5);
+        $response = inbound_remote_get( $permalink );
+		sleep(5);
+        $response = inbound_remote_get( add_query_arg( array('lp-variation-id'=> 0  ) , $permalink ) );
+		sleep(5);
+        $response = inbound_remote_get( add_query_arg( array('lp-variation-id'=> 1  ) , $permalink ) );
+		sleep(5);
+		*/
+        $stats = Landing_Pages_Statistics::read_statistics( $this->lp_id );
+        print_r($stats);
+		
+        $this->assertEquals( $stats['impressions'][0] , 3 );
+        $this->assertEquals( $stats['conversions'][0] , 0 );
+        $this->assertEquals( $stats['impressions'][1] , 3 );
+        $this->assertEquals( $stats['conversions'][1] , 0 );
+    }
+}
+
+

Vulnerable code:     public static function get_variations( $landing_page_id	, $vid = null ) {
        $variations = explode( ',' , $variations );
	width: 20px;
	color: red;
	display: block;
	color: grey;
	font-size: 10px;
	font-style: italic;
	padding: 10px;
padding-left: 4px;
padding-top: 6px;
	margin-left: 12px;
color: red;
font-size: 12px;
margin-right: 8px;
	display: inline-block;
	font-size: 11px;
	position: absolute;
	font-weight: 100;
	right: 10px;
	top: 3px;
.lp-pop-edit a{
    color:#fff;
	color: green;
	font-size: 14px;
	font-weight: bold;
	text-shadow: 1px 1px 1px rgba(255,255,255,0.5);
	color: red;
	font-size: 12px;
	display: inline-block !important;
	margin-right: 11px !important;
	margin-left: 5px !important;
    color:#333;
   text-decoration: none;
.qtip-titlebar
{
	position: relative;
	padding: 0px;
.qtip-jtools
{
	border: 2px solid rgba(172, 172, 172, 1);
	position: relative;
	margin: 0 0 5px;
	padding: 12px 17px 14px 14px;
	line-height: 19px;
	font-size: 19px;
	color: #fff;
	text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
	background: #8cc1e9;
	background-image: -webkit-gradient(linear,left bottom,left top,from(#72a7cf),to(#8cc1e9));
	background-image: -webkit-linear-gradient(bottom,#72a7cf,#8cc1e9);
	background-image: -moz-linear-gradient(bottom,#72a7cf,#8cc1e9);
	background-image: -o-linear-gradient(bottom,#72a7cf,#8cc1e9);
	background-image: linear-gradient(to top,#72a7cf,#8cc1e9);
	padding: 6px 20px;
	margin: 0;
	font-size: 13px;
	vertical-align: top;
	padding-left: 5px;
	padding-right: 5px;
.stats li:hover
{
	background:#e0e0e0;
	padding-top: 0px;
	margin-left: 4px;
	position: absolute;
	border: 1px solid #EBEBEA;
	padding-right: 0px;
.lp-current-winner{
  background-color: rgb(226, 255, 201);
	text-align: center;
	float: none;
	font-weight: normal;
	color: rgb(117, 117, 117) !important;
.wp-list-table td.impressions, .wp-list-table td.actions, .wp-list-table td.cr{
	margin: 0;
	text-align: center;
	padding-top: 15px;
	border-right: 1px solid #EBEBEA;
	font-size: 15px!important;
	margin-top: 2px !important;
	display: inline-block;
.post-state .states{
							font-size:10px;
							padding:3px 8px 3px 8px;
							-moz-border-radius:2px;
							-webkit-border-radius:2px;
							border-radius:2px;
							}
					.post-state .password{background:#000;color:#fff;}
					.post-state .pending{background:#83CF21 !important;color:#fff;}
					.post-state .private{background:#E0A21B;color:#fff;}
					.post-state .draft{background:#006699;color:#fff;}
	color: #21759b;
	font-size: 9px;
	padding-left: 10px;
.stats li:last-child{
	padding-left: 7px;
padding-top: 6px;
color: #777;
font-size: 11px;
display: none;
	font-size: 12px;
	border-top: none;
	width: 	100%;
	border-bottom: none;
	margin-bottom: -2px;
	padding-bottom: 0px;
	display: inline-block;
	margin-top: 0px;
	font-size: 13px;
	min-width: 199px;
	display: inline-block;
visibility: visible;}
	display: inline-block;
	text-align: center;
	min-width: 30px;
	padding-right: 5px;
	padding-left: 5px;
	display: inline-block;
	padding-left: 10px;
	color: #ccc;
	font-weight: bold;
	font-size: 19px;
	display: inline-block;
	min-width: 60px;
	display: inline-block;
	padding-left: 4px;
	padding-right: 4px;
	display: inline-block;

	font-size: 20px;
	min-width: 16px;
	min-height: 20px;
	border-radius: 3px;
	background: #f3f3f3;
	background-image: -webkit-gradient(linear,left top,left bottom,from(#fefefe),to(#f4f4f4));
	background-image: -webkit-linear-gradient(top,#fefefe,#f4f4f4);
	background-image: -moz-linear-gradient(top,#fefefe,#f4f4f4);
	background-image: -o-linear-gradient(top,#fefefe,#f4f4f4);
	background-image: linear-gradient(to bottom,#fefefe,#f4f4f4);
	border-color: #bbb;
	color: #333;
	text-shadow: 0 1px 0 #fff;
	font-family: sans-serif;
	cursor: pointer;
	border-width: 1px;
	border-style: solid;
	padding: 1px;
	padding-left: 4px;
	text-align: center;
	padding-right: 5px;
	padding-top: 6px;
	margin-right: 5px;
	background-image: -webkit-gradient(linear,left top,left bottom,from(#2a95c5),to(#21759b));
	background-image: -webkit-linear-gradient(top,#2a95c5,#21759b);
	background-image: -moz-linear-gradient(top,#2a95c5,#21759b);
	background-image: -ms-linear-gradient(top,#2a95c5,#21759b);
	background-image: -o-linear-gradient(top,#2a95c5,#21759b);
	background-image: linear-gradient(to bottom,#2a95c5,#21759b);
	border-color: #21759b;
	border-bottom-color: #1e6a8d;
	-webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
	box-shadow: inset 0 1px 0 rgba(120,200,230,0.5);
	color: #fff;
	text-shadow: 0 1px 0 rgba(0,0,0,0.1);
	font-weight: normal;
	margin-right: 0px !important;
	font-weight: normal !important;
color: #ccc;
box-shadow: none;
-webkit-box-shadow: none;
 a.cr-number:hover {
	background-image: -webkit-gradient(linear,left top,left bottom,from(#2e9fd2),to(#21759b));
	background-image: -webkit-linear-gradient(top,#2e9fd2,#21759b);
	background-image: -moz-linear-gradient(top,#2e9fd2,#21759b);
	background-image: -ms-linear-gradient(top,#2e9fd2,#21759b);
	background-image: -o-linear-gradient(top,#2e9fd2,#21759b);
	background-image: linear-gradient(to bottom,#2e9fd2,#21759b);
	border-color: #1b607f;
	-webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
	box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
	color: #fff;
	text-shadow: 0 -1px 0 rgba(0,0,0,0.3);
}
Version: 1.8.6
			define('LANDINGPAGES_CURRENT_VERSION', '1.8.6' );
		}
			if ($current_variation_id>0)
			{
				foreach($wpdb->last_result as $k => $v){
					$data[$v->meta_key] =   $v->meta_value;
				};
				//echo $len;exit;
				foreach ($data as $key=>$value)
				{
					if (substr($key,-$len)==$suffix)
					{
						delete_post_meta($_GET['post'], $key, $value);
					}
				}

				$_GET['lp-variation-id'] = $current_variation_id;
			}

			//check for pause command
			if (isset($_GET['ab-action'])&&$_GET['ab-action']=='pause-variation')
			{
				if ($_GET['lp-variation-id']==0)
				{
					update_post_meta( $post->ID , 'lp_ab_variation_status' , '0' );
				}
				else
				{
					update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '0');
				}
			}

			//check for pause command
			if (isset($_GET['ab-action'])&&$_GET['ab-action']=='play-variation')
			{
				if ($_GET['lp-variation-id']==0)
				{
					update_post_meta( $post->ID , 'lp_ab_variation_status' , '1' );
				}
				else
				{
					update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '1');
				}
			}

			//return;

			(isset($_GET['new-variation'])&&$_GET['new-variation']==1) ? $new_variation = 1 : $new_variation = 0;

			$content_area = lp_content_area($post,null,true);

			//prepare for new variation creation - use A as default content if not being cloned
			if (($new_variation==1&&!isset($_GET['clone']))||isset($_GET['clone'])&&$_GET['clone']==0)
			{
				$content_area = get_post_field('post_content', $_GET['post']);
				$content_area = wpautop($content_area);
			}
			else if ($new_variation==1&&isset($_GET['clone']))
			{
				$content_area = get_post_field('content-'.$_GET['clone'], $_GET['post']);
				$content_area = wpautop($content_area);
			}

			//if new variation and cloning then programatically prepare the next variation id
			if($new_variation==1&&isset($_GET['clone']))
			{
				$array_variations = explode(',',$variations);
				sort($array_variations,SORT_NUMERIC);

				$lid = end($array_variations);
				$current_variation_id = $lid+1;

				$_SESSION['lp_ab_test_open_variation'] = $current_variation_id;
			}
			//echo $current_variation_id;exit;
			//enqueue and localize scripts
			wp_enqueue_style('lp-ab-testing-admin-css', LANDINGPAGES_URLPATH . 'css/admin-ab-testing.css');
			wp_enqueue_script('lp-ab-testing-admin-js', LANDINGPAGES_URLPATH . 'js/admin/admin.post-edit-ab-testing.js', array( 'jquery' ));
			wp_localize_script( 'lp-ab-testing-admin-js', 'variation', array( 'pid' => $_GET['post'], 'vid' => $current_variation_id  , 'new_variation' => $new_variation  , 'variations'=> $variations  , 'content_area' => $content_area  ));

		}

	}

	/* force visual editor to open in text mode */

	function lp_ab_testing_force_default_editor() {
		//allowed: tinymce, html, test
		return 'html';
	}

	add_filter('lp_edit_main_headline','lp_ab_testing_admin_prepare_headline');
	function lp_ab_testing_admin_prepare_headline($main_headline)
	{

		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if (isset($_REQUEST['post']))
		{
			$post_id = $_REQUEST['post'];
		}
		else if (isset($_REQUEST['lp_id']))
		{
			$post_id = $_REQUEST['lp_id'];
		}

		//return "hello";

		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
		{
			$main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
		}
		else if (isset($_GET['clone'])&&$_GET['clone']>0)
		{
			$main_headline = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
		}

		if (!$main_headline&&isset($_REQUEST['post']))
		{
			get_post_meta($_REQUEST['post'],'lp-main-headline', true);
		}

		return $main_headline;
	}

	//disable this because it will populate all wp_editor isntances rather than targeted instances
	//add_filter('the_editor_content', 'lp_ab_testing_the_editor_content');
	function lp_ab_testing_the_editor_content($content) {
		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if (isset($_REQUEST['post']))
		{
			$post_id = $_REQUEST['post'];
		}
		else if (isset($_REQUEST['lp_id']))
		{
			$post_id = $_REQUEST['lp_id'];
		}

		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
		{
			$content = get_post_field('content-'.$current_variation_id, $post_id);
		}
		else if (isset($_GET['clone']))
		{
			$content = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
		}

		return $content;
	}


	add_filter('lp_edit_variation_notes','lp_ab_testing_admin_prepare_notes');
	function lp_ab_testing_admin_prepare_notes($variation_notes)
	{
		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if (isset($_REQUEST['post']))
		{
			$post_id = $_REQUEST['post'];
		}
		else if (isset($_REQUEST['lp_id']))
		{
			$post_id = $_REQUEST['lp_id'];
		}

		//return "hello";

		if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
		{
			$variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$current_variation_id, true);
		}
		else if (isset($_GET['clone'])&&$_GET['clone']>0)
		{
			$variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$_GET['clone'], true);
		}

		if (!$variation_notes&&isset($_REQUEST['post']))
		{
			get_post_meta($_REQUEST['post'],'lp-variation-notes', true);
		}

		return $variation_notes;
	}

	add_filter('lp_selected_template_id','lp_ab_testing_prepare_id');//prepare name id for hidden selected template input
	add_filter('lp_display_headline_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
	add_filter('lp_display_notes_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
	function lp_ab_testing_prepare_id($id)
	{
		$current_variation_id = lp_ab_testing_get_current_variation_id();

		//check if variation clone is initiated
		if (isset($_GET['new_meta_key']))
			$current_variation_id = $_GET['new_meta_key'];

		if ($current_variation_id>0)
		{
			$id = $id.'-'.$current_variation_id;
		}

		return $id;
	}

	//prepare id for wp_editor in template customizer
	add_filter('lp_wp_editor_id','lp_ab_testing_prepare_wysiwyg_editor_id');
	function lp_ab_testing_prepare_wysiwyg_editor_id($id)
	{
		$current_variation_id = lp_ab_testing_get_current_variation_id();
		//echo $current_variation_id;exit;
		if ($current_variation_id>0)
		{
			switch ($id) {
				case "wp_content":
					$id = 'content-'.$current_variation_id;
					break;
				case "lp-conversion-area":
					$id = 'landing-page-myeditor-'.$current_variation_id;
					break;
				default:
					$id = $id.'-'.$current_variation_id;
			}

		}

		return $id;
	}


	add_filter('lp_show_metabox','lp_ab_testing_admin_prepare_meta_ids', 5, 2);
	function lp_ab_testing_admin_prepare_meta_ids($lp_custom_fields, $main_key)
	{
		if (isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
		{
			return $lp_custom_fields;
		}

		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if (isset($_GET['clone'])) {
			$current_variation_id = $_GET['clone'];
		}

		if ($current_variation_id>0)
		{
			$post_id = $_GET['post'];
			foreach ($lp_custom_fields as $key=>$field)
			{
				$default = get_post_meta($post_id, $field['id'], true);

				$id = $field['id'];
				$field['id'] = $id.'-'.$current_variation_id ;

				if ($default) {
					$field['default'] = $default;
				}

				$lp_custom_fields[$key] = $field;
			}
			return $lp_custom_fields;
		}

		//print_r($lp_custom_fields);exit;
		return $lp_custom_fields;
	}

	add_filter('lp_variation_selected_template','lp_ab_testing_lp_variation_selected_template', 10, 2);
	function lp_ab_testing_lp_variation_selected_template($selected_template, $post)
	{
		if (isset($_GET['new-variation']))
			return $selected_template;

		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if ($current_variation_id>0)
		{
			$selected_template = get_post_meta( $post->ID , 'lp-selected-template-'.$current_variation_id , true);
		}

		//print_r($lp_custom_fields);exit;
		return $selected_template;
	}

	//add filter to modify thumbnail preview
	add_filter('lp_live_screenshot_url', 'lp_ab_testing_prepare_screenshot');
	function lp_ab_testing_prepare_screenshot($link)
	{
		$variation_id = lp_ab_testing_get_current_variation_id();
		$link = $link."?lp-variation-id=".$variation_id;
		return $link;
	}



	add_filter("post_type_link", "lp_ab_append_variation_id_to_adminbar_link", 10,2);
	function lp_ab_append_variation_id_to_adminbar_link($link, $post)
	{
		if( $post->post_type == 'landing-page' )
		{
			$current_variation_id = lp_ab_testing_get_current_variation_id();

			if ($current_variation_id>0)
				$link = $link."?lp-variation-id=".$current_variation_id;
		}

		return $link;
	}

	if(!defined('AUTOSAVE_INTERVAL')) {
    define('AUTOSAVE_INTERVAL', 86400);
	}
	function lp_ab_testing_wp_insert_post_data($data,$postarr)
	{

		//exit;
		//$variation_id = lp_ab_testing_get_current_variation_id();
		//echo $variation_id;exit;
		if (isset($postarr['lp-variation-id'])&&$postarr['lp-variation-id']>0)
		{
			$postarr = array();
			$data = array();

			remove_action('save_post','lp_save_meta',10);
			remove_action('save_post','lp_ab_testing_save_post',10);

			$postID = $_POST['post_ID'];
			if($parent_id = wp_is_post_revision($_POST['post_ID']))
			{
				$postID = $parent_id;
			}

			lp_ab_testing_save_post($postID);

		}
		else
		{
			//echo "here";exit;
			//$this_data = json_encode($data);
			//mail('hudson.atwell@gmail.com','test2',$this_data);
		}

		if (count($data)>1)
			return $data;
	}

	add_action('save_post','lp_ab_testing_save_post');
	function lp_ab_testing_save_post($postID)
	{
		global $post;

		$var_final = (isset($_POST['lp-variation-id'])) ? $_POST['lp-variation-id'] : '0';
		if (  isset($_POST['post_type']) && $_POST['post_type']=='landing-page')
		{
			if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||$_POST['post_type']=='revision')
			{
				return;
			}

			if($parent_id = wp_is_post_revision($postID))
			{
				$postID = $parent_id;
			}


			$this_variation = $var_final;
			//echo $this_variation;
			//print_r($_POST);exit;

			//first add to varation list if not present.
			$variations = get_post_meta($postID,'lp-ab-variations', true);
			if ($variations)
			{
				$array_variations = explode(',',$variations);
				if (!in_array($this_variation,$array_variations))
				{
					$array_variations[] = $this_variation;
				}
			}
			else
			{
				if  ($this_variation>0)
				{
					$array_variations[] = 0;
					$array_variations[] = $this_variation;
				}
				else
				{
					$array_variations[] = $this_variation;
				}
			}

			//print_r($array_variations);exit;
			//update_post_meta($postID,'lp-ab-variations', "");
			update_post_meta($postID,'lp-ab-variations', implode(',',$array_variations));
			//add_post_meta($postID, 'lp_ab_variation_status-'.$this_variation , 1);

			//echo $this_variation;exit;
			if ($this_variation==0)
			{
				return;
			}
			//echo $this_variation;exit;
			//print_r($_POST);

			//next alter all custom fields to store correct varation and create custom fields for special inputs
			$ignore_list = array('post_status','post_type','tax_input','post_author','user_ID','post_ID','catslist','post_title','samplepermalinknonce',
			'autosavenonce','action','autosave','mm','jj','aa','hh','mn','ss','_wp_http_referer','lp-variation-id','_wpnonce','originalaction','original_post_status',
			'referredby','_wp_original_http_referer','meta-box-order-nonce','closedpostboxesnonce','hidden_post_status','hidden_post_password','hidden_post_visibility','visibility',
			'post_password','hidden_mm','cur_mm','hidden_jj','cur_jj','hidden_aa','cur_aa','hidden_hh','cur_hh','hidden_mn','cur_mn','original_publish','save','newlanding_page_category','newlanding_page_category_parent',
			'_ajax_nonce-add-landing_page_category','lp_lp_custom_fields_nonce','lp-selected-template','post_mime_type','ID','comment_status','ping_status');

			//$special_list = array('content','post-content');
			//print_r($_POST);exit;
			//echo $this_variation;exit;
			foreach ($_POST as $key=>$value)
			{
				//echo $key." : -{$this_variation} : $value<br>";
				if (!in_array($key,$ignore_list)&&!strstr($key,'nonce'))
				{
					if ($key=='post_content')
						$key = 'content';

					if (!strstr($key,"-{$this_variation}"))
					{
						$new_array[$key.'-'.$this_variation] = $value;
					}
					else
					{
						//echo $key." : -{$this_variation}<br>";
						$new_array[$key] = $value;
					}
				}
				//echo $key." : -{$this_variation} : $value<br>";
			}

			//print_r($new_array);exit;

			foreach($new_array as $key => $val)
			{
				$old = get_post_meta($postID, $key, true);
				$new = $val;
				//echo "$key  : $old v. $new <br>";
				//if (isset($new) && $new != $old ) {
					update_post_meta($postID, $key, $new);
				//} elseif ('' == $new && $old) {
					//delete_post_meta($postID, $key, $old);
				//}
			}

		}
	}
	//prepare customizer meta data for ab varations
	add_filter('lp_get_value','lp_ab_testing_prepare_variation_meta', 1 , 4);
	function lp_ab_testing_prepare_variation_meta($return, $post, $key, $id)
	{
		if (isset($_REQUEST['lp-variation-id'])||isset($_COOKIE['lp-variation-id']))
		{
			(isset($_REQUEST['lp-variation-id'])) ? $variation_id = $_REQUEST['lp-variation-id'] : $variation_id = $_COOKIE['lp-variation-id'];
			if ($variation_id>0)
					return do_shortcode(get_post_meta($post->ID, $key.'-'.$id. '-' .$variation_id , true));
			else
				return $return;
		}
		else
		{
			return $return;
		}
	}

	//prepare customizer, admin, and preview links for variations
	add_filter('lp_customizer_customizer_link', 'lp_ab_append_variation_id_to_link');
	add_filter('lp_customizer_admin_bar_link', 'lp_ab_append_variation_id_to_link');
	add_filter('lp_customizer_preview_link','lp_ab_append_variation_id_to_link');

	function lp_ab_append_variation_id_to_link($link)
	{

		$current_variation_id = lp_ab_testing_get_current_variation_id();

		if ($current_variation_id>0)
			$link = $link."&lp-variation-id=".$current_variation_id;

		return $link;
	}
	global $post;
	$variation_id = lp_ab_testing_get_current_variation_id();
	if ($variation_id>0)
	{
		$content = get_post_meta($post->ID,'content-'.$variation_id, true);
		if ( !is_admin() )
		{
			$content = wpautop($content);
			$content = do_shortcode($content);
		}
	}
	return $content;
                       'F', 'G', 'H', 'I', 'J',
                       'K', 'L', 'M', 'N', 'O',
                       'P', 'Q', 'R', 'S', 'T',
                       'U', 'V', 'W', 'X', 'Y',
                       'Z'
                       );

	if (isset($alphabet[$key])) {
		return $alphabet[$key];
	}
	if ( isset($_GET['ab-action']) &&is_admin())
	{
		return $_SESSION['lp_ab_test_open_variation'];
	}

	if (!isset($_SESSION['lp_ab_test_open_variation'])&&!isset($_REQUEST['lp-variation-id']))
	{
		$current_variation_id = 0;
	}
	//echo $_REQUEST['lp-variation-id'];
	if (isset($_REQUEST['lp-variation-id']))
	{
		$_SESSION['lp_ab_test_open_variation'] = $_REQUEST['lp-variation-id'];
		$current_variation_id = $_REQUEST['lp-variation-id'];
		//echo "setting session $current_variation_id";
	}

	if (isset($_GET['message'])&&$_GET['message']==1&&isset( $_SESSION['lp_ab_test_open_variation'] ))
	{
		$current_variation_id = $_SESSION['lp_ab_test_open_variation'];

		//echo "here:".$_SESSION['lp_ab_test_open_variation'];
	}

	if (isset($_GET['ab-action'])&&$_GET['ab-action']=='delete-variation')
	{
		$current_variation_id = 0;
		$_SESSION['lp_ab_test_open_variation'] = 0;
	}

	if (!isset($current_variation_id))
		$current_variation_id = 0 ;

	return $current_variation_id;
	$current_variation_id = lp_ab_testing_get_current_variation_id();

	if (isset($post))
	{
		$post_id = $post->ID;
	}
	else if (isset($_REQUEST['post']))
	{
		$post_id = $_REQUEST['post'];
	}
	else if (isset($_REQUEST['lp_id']))
	{
		$post_id = $_REQUEST['lp_id'];
	}


	if ($current_variation_id>0)
		$content = get_post_meta($post_id,'landing-page-myeditor-'.$current_variation_id, true);

	return $content;
	$current_variation_id = lp_ab_testing_get_current_variation_id();

	if (isset($post))
	{
		$post_id = $post->ID;
	}
	else if (isset($_REQUEST['post']))
	{
		$post_id = $_REQUEST['post'];
	}
	else if (isset($_REQUEST['lp_id']))
	{
		$post_id = $_REQUEST['lp_id'];
	}

	if ($current_variation_id>0)
		$position = get_post_meta($post->ID, "{$key}-conversion-area-placement-".$current_variation_id, true);

	return $position;
	$current_variation_id = lp_ab_testing_get_current_variation_id();
	if (isset($post))
	{
		$post_id = $post->ID;
	}
	else if (isset($_REQUEST['post']))
	{
		$post_id = $_REQUEST['post'];
	}
	else if (isset($_REQUEST['lp_id']))
	{
		$post_id = $_REQUEST['lp_id'];
	}
	else if (isset($_REQUEST['post_id']))
	{
		$post_id = $_REQUEST['post_id'];
	}
	if ($current_variation_id>0)
		$main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
	if (!$main_headline)
	{
		get_post_meta($post_id,'lp-main-headline', true);
	}
	return $main_headline;
	$this_path = LANDINGPAGES_PATH;
	$this_path = explode('wp-content',$this_path);
	$this_path = "wp-content".$this_path[1];

	$slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
	//echo $slug;exit;
	$ab_testing = get_option( 'lp-main-landing-page-disable-turn-off-ab', "0");
	if($ab_testing === "0") {
	add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2",'top');
	add_rewrite_rule("$slug/([^/]*)?", $this_path."modules/module.redirect-ab-testing.php?permalink_name=$1 ",'top');
	add_rewrite_rule("landing-page=([^/]*)?", $this_path.'modules/module.redirect-ab-testing.php?permalink_name=$1','top');
	}
	add_filter('mod_rewrite_rules', 'lp_ab_testing_modify_rules', 1);
	function lp_ab_testing_modify_rules($rules)
	{
		if (!stristr($rules,'RewriteCond %{QUERY_STRING} !lp-variation-id'))
		{
			$rules_array = preg_split ('/$\R?^/m', $rules);
			if (count($rules_array)<3)
			{
				$rules_array = explode("\n", $rules);
				$rules_array = array_filter($rules_array);
			}

			//print_r($rules_array);exit;

			$this_path = LANDINGPAGES_PATH;
			$this_path = explode('wp-content',$this_path);
			$this_path = "wp-content".$this_path[1];
			$slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );

			$i = 0;
			foreach ($rules_array as $key=>$val)
			{

				if ( stristr($val,"RewriteRule ^{$slug}/([^/]*)? ") ||  stristr($val,"RewriteRule ^{$slug}/([^/]*)/([0-9]+)/ ") )
				{
					$new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
					$rules_array[$i] = $new_val;
					$i++;
					$rules_array[$i] = $val;
					$i++;
				}
				else
				{
					$rules_array[$i] = $val;
					$i++;
				}
			}

			$rules = implode("\r\n", $rules_array);
		}

		return $rules;
	}
	global $post;
	$current_variation_id = lp_ab_testing_get_current_variation_id();
	if ($current_variation_id>0)
	{
		$new_template =  get_post_meta($post->ID, 'lp-selected-template-'.$current_variation_id, true);
		if ($new_template)
			$template = $new_template;
	}
	return $template;
	$current_variation_id = lp_ab_testing_get_current_variation_id();
	//echo $current_variation_id;exit;
	if ($current_variation_id>0)
	{
		$id = $id.'-'.$current_variation_id;
	}

	return $id;
	$page_id = lp_url_to_postid( trim($_POST['current_url']) );
	$variations = get_post_meta($page_id,'lp-ab-variations', true);
	$marker = get_post_meta($page_id,'lp-ab-variations-marker', true);
	if (!is_numeric($marker)) {
		$marker = 0;
	}
	if ($variations)
	{
		//echo $variations;
		$variations = explode(',',$variations);
		//print_r($variations);
		$variation_id = $variations[$marker];
		$marker++;
		if ($marker>=count($variations))
		{
			//echo "here";
			$marker = 0;
		}
		update_post_meta($page_id, 'lp-ab-variations-marker', $marker);
		echo $variation_id;
		die();
	}
	global $post;
	if ( !isset($post) || $post->post_type != 'landing-page' ) {
		return $content;
	}
	$variation_id = lp_ab_testing_get_current_variation_id();
	if ($variation_id>0)
	{
		$content = do_shortcode(get_post_meta($post->ID,'content-'.$variation_id, true));
	}
	return $content;
	global $post;
	if (!isset($post))
		return $content;
	if ( ( $post->post_type!='landing-page'||is_admin()) || $id != $post->ID)
		return $content;
	return lp_main_headline($post, null, true);
	/* If Landing Page Post Type */
	if ( $post_type == 'landing-page' ) {
		$meta_key = 'lp-ab-variation-impressions-'.$variation_id;
	}
	/* If Non Landing Page Post Type */
	else  {
		$meta_key = '_inbound_impressions_count';
	}
	$impressions = get_post_meta($post_id, $meta_key , true);
	if (!is_numeric($impressions)) {
		$impressions = 1;
	} else {
		$impressions++;
	}
	update_post_meta($post_id, $meta_key , $impressions);
	$permalink = get_permalink( $post->ID );
	$randomstring = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
	wp_enqueue_script( 'lp_ab_testing_customizer_js', LANDINGPAGES_URLPATH . 'js/customizer.ab-testing.js', array( 'jquery' ) );
	wp_localize_script( 'lp_ab_testing_customizer_js', 'ab_customizer', array( 'lp_id' => $post->ID ,'permalink' => $permalink , 'randomstring' => $randomstring));
	wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'css/customizer-ab-testing.css');

    $current_user = wp_get_current_user();
    $default_lander = wp_insert_post(
            array(
                'post_title'     => __( 'A/B Testing Landing Page Example' , 'landing-pages'),
                'post_content'   => __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages'),
                'post_status'    => 'publish',
                'post_author'    => $current_user->ID,
                'post_type'      => 'landing-page',
                'comment_status' => 'closed'
            )
        );
    add_post_meta($default_lander, 'lp-main-headline', __( 'Main Catchy Headline (A)' , 'landing-pages') );
    add_post_meta($default_lander, 'lp-selected-template', 'svtle');
    add_post_meta($default_lander, 'svtle-conversion-area-content', '<h2>'.__( 'Form a' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]' );
    add_post_meta($default_lander, 'svtle-main-content', __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages') );
    add_post_meta($default_lander, 'lp-main-headline-1', __('Main Catchy Headline Two (B)' , 'landing-pages') );
    add_post_meta($default_lander, 'lp-selected-template-1', 'svtle');
    add_post_meta($default_lander, 'svtle-conversion-area-content-1', '<h2>'.__( 'Form B' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]');
    add_post_meta($default_lander, 'svtle-main-content-1', '<p>(Version B) This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>');
    add_post_meta($default_lander, 'lp-ab-variations', '0,1');
    add_post_meta($default_lander, 'lp-ab-variation-impressions-0', 30);
    add_post_meta($default_lander, 'lp-ab-variation-impressions-1', 35);
    add_post_meta($default_lander, 'lp-ab-variation-conversions-0', 10);
    add_post_meta($default_lander, 'lp-ab-variation-conversions-1', 15);
    add_post_meta($default_lander, 'svtle-submit-button-color', '5baa1e');
    add_post_meta($default_lander, 'svtle-display-social', '0');
    add_post_meta($default_lander, 'svtle-logo', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
    add_post_meta($default_lander, 'svtle-body-color', 'ffffff');
    add_post_meta($default_lander, 'svtle-sidebar', 'left');
    add_post_meta($default_lander, 'svtle-page-text-color', '4d4d4d');
    add_post_meta($default_lander, 'svtle-sidebar-color', 'ffffff');
    add_post_meta($default_lander, 'svtle-sidebar-text-color', '000000');
    add_post_meta($default_lander, 'svtle-header-color', 'ffffff');
    add_post_meta($default_lander, 'svtle-submit-button-color-1', 'ff0c00');
    add_post_meta($default_lander, 'svtle-display-social-1', '0');
    add_post_meta($default_lander, 'svtle-logo-1', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
    add_post_meta($default_lander, 'svtle-body-color-1', '51b0ef');
    add_post_meta($default_lander, 'svtle-sidebar-1', 'left');
    add_post_meta($default_lander, 'svtle-page-text-color-1', '000000');
    add_post_meta($default_lander, 'svtle-sidebar-color-1', '51b0ef');
    add_post_meta($default_lander, 'svtle-sidebar-text-color-1', '000000');
    add_post_meta($default_lander, 'svtle-header-color-1', '51b0ef');
        "default_landing_page" => $default_lander
    update_option( "lp_settings_general", $options );
    return $default_lander;

      /*  array(
            'name'                  => 'TGM Example Plugin', // The plugin name
            'slug'                  => 'tgm-example-plugin', // The plugin slug (typically the folder name)
            'source'                => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
            'required'              => true, // If false, the plugin is only 'recommended' instead of required
            'version'               => '', // E.g. 1.0.0. If set, the active plugin must be this version or higher, otherwise a notice is presented
            'force_activation'      => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch
            'force_deactivation'    => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins
            'external_url'          => '', // If set, overrides default API URL and points to an external URL
        ), */
       array(
           'name'      => __('WordPress Calls to Action' , 'landing-pages') .' <span class=\'inbound-install-notice\'> - '. __('This <b>free</b> landing page addon will drive more traffic into your Landing Pages with Targeted Calls to Action in your sites sidebars & content. Create popups to capture visitor attention and convert more leads.' , 'landing-pages') . ' <a class=\'inbound-install-notice-links\' href=\'http://wordpress.org/plugins/cta/\'> ' . __('Learn more about WordPress Calls to Action' , 'landing-pages') . '</a></span>',
           'slug'      => 'cta',
           'required'  => false,
       ),
             // %1$s = dashboard link
<phpunit bootstrap="tests/travis-ci/bootstrap.php" backupGlobals="false" colors="true">
            <directory prefix="test." suffix=".php">tests/travis-ci/</directory>
Stable Tag: 1.8.6
  background-image: url('../../images/global/shortcodes-blue.png');
  background-repeat: no-repeat;
  background-position: 0.15em 50%;
  padding-left: 22px;
  padding-left: 5px;
.inbound-nav-marketing div:first-of-type{
  color:rgba(240,245,250,1);
 display: none;
 .switch-versions,  .switch-versions {
  color: #ff9900;
  content: '• ';
  width: 140px;
  color: #21759b !important;
  text-shadow: none;
  background-color: #fff;
  height: 18px;
  line-height: 18px;
  padding: 1px 4px;
  -webkit-border-radius: 11px;
     -moz-border-radius: 11px;
          border-radius: 11px;
  font-size: 0.67em;
  margin: 0 0 0 2px;
  font-family: 'FontAwesome';
  src: url('../../fonts/fontawesome/fontawesome-webfont.eot');
  src: url('../../fonts/fontawesome/fontawesome-webfont.eot') format('embedded-opentype'),
  url('../../fonts/fontawesome/fontawesome-webfont.woff?v=3.0.2') format('woff'),
  url('../../fonts/fontawesome/fontawesome-webfont.ttf?v=3.0.2') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-family: "FontAwesome" !important;
  content: "\f0c0";
display: none;
#adminmenu .menu-icon-wp-lead div.wp-menu-image img{
  display: none;
  display: block;
  padding-left: 30px !important;
  color: #2ea2cc;
  padding-left: 31px !important;
  max-height: 22px !important;
  padding: 0px !important;
  min-height: 23px !important;
  padding-left: 3px !important;
  margin-bottom: 1px !important;
}
#wp-admin-bar-inbound-docs-searchform, #wp-admin-bar-inbound-leads-search{
  margin-bottom: 10px !important;
}
#wp-admin-bar-inbound-cta .ab-submenu a, #wp-admin-bar-inbound-leads .ab-submenu a,  #wp-admin-bar-inbound-landingpages .ab-submenu a , #wp-admin-bar-inbound-forms .ab-submenu a, #wp-admin-bar-inbound-templates .ab-submenu a,  #wp-admin-bar-inbound-analytics .ab-submenu a, #wp-admin-bar-inbound-seo .ab-submenu a{
  padding-left: 10px !important;
}
 #wp-admin-bar-inbound-cta:before, #wp-admin-bar-inbound-leads:before, #wp-admin-bar-inbound-landingpages:before, #wp-admin-bar-inbound-forms:before, #wp-admin-bar-inbound-templates:before, #wp-admin-bar-inbound-settings:before, #wp-admin-bar-inbound-analytics:before, #wp-admin-bar-inbound-seo:before  {
  font-family: "FontAwesome" !important;
  content: "\f05b" !important;
  font: 100 19px/1 "FontAwesome" !important;
  padding-top: 4px;
  width: 30px;
  display: inline-block;
  height: 30px;
  position: absolute;
  left: 6px;
  content: "\f0c0" !important;
  font: 100 17px/1 "FontAwesome" !important;
  content: "\f15c" !important;
  left: 7px;
  font-size: 21px !important;
  }
    font: 400 18px/1 dashicons!important;
  }
  }
  content: "\f013" !important;
  left: 7px !important;
  content: "\f012" !important;
  font-size: 17px !important;
  content: "\f002" !important;
  font-size: 17px !important;
  vertical-align: top;
  font-family: "FontAwesome" !important;
  content: "\f05b";
  font: 400 24px/1 "FontAwesome" !important;
  padding-top: 6px;
position: absolute;
top: 0;
left: 0;
width: 22px;
				$form_id = (isset($_GET['post'])) ? $_GET['post'] : '';
							    if ( isset($_REQUEST['post']) ) {
input[type="text"], input[type="email"], #inbound-form-wrapper input[type=text], #inbound-form-wrapper input[type=url], #inbound-form-wrapper input[type=email], #inbound-form-wrapper input[type=tel], #inbound-form-wrapper input[type=number], #inbound-form-wrapper input[type=password] {
Fixed code: <?php


class Landing_Pages_Load_Extensions {
	
	/**
	*  Initializes Landing_Pages_Load_Extensions
	*/
	public function __construct() {
		
		/* Load core landing page config.php files */
		self::load_core_template_configurations();
		
		/* Load uploaded landing page config.php files */
		self::load_uploaded_template_configurations();
		
		/* load hooks & filters  */
		self::load_hooks();
	}

	/**
	*  Loads hooks and filiters
	*/
	public static function load_hooks() {
		
		/* Adds core metabox settings to extension data array */
		add_filter( 'lp_extension_data' , array( __CLASS__ , 'add_core_setting_data' ) , 1 , 1);
		
		/* Modifies legacy template data key names for old, un-updated legacy templates */
		add_filter( 'lp_extension_data', array( __CLASS__ , 'add_legacy_data_support') , 10 , 1 );
		
		/* Add license key inputs to all uploaded templates */
		add_filter( 'lp_define_global_settings' , array( __CLASS__ , 'prepare_license_keys' ), 99, 1);
	}
	
	/**
	*  Adds core metaboxes setting data using lp_extension_data filter
	*/
	public static function add_core_setting_data( $data ) {
		
		if ( !is_admin() ) {
			return;
		}
		
		$data[ 'lp' ]['settings'] = 	array(
			array(
				'id'  => 'selected-template',
				'label' => __( 'Select Template' , 'landing-pages'),
				'description' =>  __( "This option provides a placeholder for the selected template data." , 'landing-pages'),
				'type'  => 'radio', // this is not honored. Template selection setting is handled uniquely by core.
				'default'  => 'default',
				'options' => null // this is not honored. Template selection setting is handled uniquely by core.
			),
			array(
				'id'  => 'main-headline',
				'label' => __('Set Main Headline' , 'landing-pages'),
				'description' => __( "Set Main Headline" , 'landing-pages'),
				'type'  => 'text', // this is not honored. Main Headline Input setting is handled uniquely by core.
				'default'  => '',
				'options' => null
			),
		);
		
		return $data;
	}
	
	/**
	*  Looks for occurances of 'options' in template & extension data arrays and replaces key with 'settings'
	*/
	public static function add_legacy_data_support( $data ) {
		if ( !is_admin() ) {
			return;
		}
		
		foreach ($data as $parent_key => $subarray)
		{
			if (is_array($subarray))
			{
				foreach ($subarray as $k=>$subsubarray)
				{
					/* change 'options' key to 'settings' */
					if ($k=='options')
						$data[$parent_key]['settings'] = $subsubarray;

					if ($k=='category')
						$data[$parent_key]['info']['category'] = $subsubarray;

					if ($k=='version')
						$data[$parent_key]['info']['version'] = $subsubarray;

					if ($k=='label')
						$data[$parent_key]['info']['label'] = $subsubarray;

					if ($k=='description')
						$data[$parent_key]['info']['description'] = $subsubarray;
				}
			}
		}

		return $data;
	}
	
	/**
	*  Adds licensing & automatic updates to uploaded templates
	*  
	*  @param ARRAY $global_settings contains all global setting data
	*  
	*  @retuns ARRAY $global_settings contains modified global setting data
	*/
	public static function prepare_license_keys( $global_settings ) {
		
		if ( !is_admin() ) {
			return;
		}
		
		$lp_data = self::get_extended_data();

		$global_settings['lp-license-keys']['settings'][] = 	array(
				'id'  => 'template-license-keys-header',
				'description' => __( "Head to http://www.inboundnow.com/ to retrieve your license key for this template." , 'landing-pages') ,
				'type'  => 'header',
				'default' => '<h3 class="lp_global_settings_header">' . __('Template Licensing' , 'landing-pages') .'</h3>'
		);

		/* get master license key */
		$inboundnow_master_key = get_option('inboundnow_master_license_key' , '');

		/* Loop through all setting data and add licensing for uploaded templates only */
		foreach ($lp_data as $key=>$data)
		{

			$array_core_templates = array('simple-solid-lite','countdown-lander','default','demo','dropcap','half-and-half','simple-two-column','super-slick','svtle','tubelar','rsvp-envelope', 'three-column-lander');

			if ($key == 'lp' || substr($key,0,4) == 'ext-' ) {
				continue;
			}
			
			if (isset($data['info']['data_type']) && $data['info']['data_type']=='metabox') {
				continue;
			}
			
			if (in_array($key,$array_core_templates)) {
				continue;
			}

			$template_name = $lp_data[$key]['info']['label'];
			$global_settings['lp-license-keys']['settings'][$key] = 	array(
				'id'  => $key,
				'label' => $template_name,
				'slug' => $key,
				'description' => __( "Head to http://www.inboundnow.com/ to retrieve your license key for this template." , 'landing-pages') ,
				'type'  => 'license-key'
			);
		}

		return $global_settings;
	}
	
	/**
	* Loads core template config.php files
	*
	* @returns ARRAY contains template setting data
	*/
	public static function load_core_template_configurations() {
		
		if ( !is_admin() ) {
			return;
		}
		
		$template_ids = self::get_core_template_ids();

		//Now load all config.php files with their custom meta data
		if (count($template_ids)>0)
		{
			foreach ($template_ids as $name)
			{
				if ($name != ".svn" && $name != ".git"){
				include_once( LANDINGPAGES_PATH . "/templates/$name/config.php");
				}
			}
		}
		
		
		/* Store all template config files in global */
		$GLOBALS['lp_data'] = $lp_data;
		
		return $lp_data;
	}
	
	/**
	* Loads uploaded template config.php files
	*
	*/
	public static function load_uploaded_template_configurations() {
		global $lp_data;
		
		$template_ids = self::get_uploaded_template_ids();

		/* loop through template ids and include their config file */
		foreach ($template_ids as $name)
		{
			$match = FALSE;
			if (strpos($name, 'tmp') !== FALSE || strpos($name, 'template-generator') !== FALSE) {
				$match = TRUE;
			}
			if ($name != ".svn" && $name != ".git" && $name != 'template-generator' && $match === FALSE){
				if (file_exists( LANDINGPAGES_UPLOADS_PATH . "$name/config.php")) {
					include_once( LANDINGPAGES_UPLOADS_PATH . "$name/config.php");					
				}
			}
		}
		
		
		return $lp_data;		

	}
	
	/**
	* Gets array of uploaded template paths
	*
	* @returns ARRAY $template_ids array of uploaded template ids
	*/
	public static function get_uploaded_template_ids()
	{
		$template_ids = array();

		if (!is_dir( LANDINGPAGES_UPLOADS_PATH )) {
			wp_mkdir_p( LANDINGPAGES_UPLOADS_PATH );
		}

		$results = scandir( LANDINGPAGES_UPLOADS_PATH );

		foreach ($results as $name) {
			if ($name === '.' or $name === '..' or $name === '__MACOSX') continue;

			if (is_dir( LANDINGPAGES_UPLOADS_PATH . '/' . $name)) {
				$template_ids[] = $name;
			}
		}

		return $template_ids;
	}
	
	/**
	* Gets array of uploaded template paths
	*
	* @returns ARRAY $template_ids array of uploaded template ids
	*/
	public static function get_core_template_ids()
	{
		$template_ids = array();
		
		$template_path = LANDINGPAGES_PATH."/templates/" ;
		$results = scandir($template_path);

		//scan through templates directory and pull in name paths
		foreach ($results as $name) {
			if ($name === '.' or $name === '..' or $name === '__MACOSX') continue;

			if (is_dir($template_path . '/' . $name)) {
				$template_ids[] = $name;
			}
		}

		return $template_ids;
	}
	
	/**
	*  Get's array of template categories from loaded templates
	*  
	*  @returns ARRAY $template_cats array if template categories
	*/	
	public static function get_template_categories()
	{
		$template_settings = self::get_extended_data();	
		
		foreach ($template_settings as $key=>$val)
		{
			if ( $key=='lp' || substr($key,0,4)=='ext-' || isset($val['info']['data_type']) && $val['info']['data_type']=='metabox' ) {
				continue;
			}
			
			/* account for legacy data models */
			if (isset($val['category'])) {
				$cats = $val['category'];
			} else	{
				if (isset($val['info']['category'])) {
					$cats = $val['info']['category'];
				}
			}

			$cats = explode(',',$cats);

			foreach ($cats as $cat_value)
			{
				$cat_value = trim($cat_value);
				$name = str_replace(array('-','_'),' ',$cat_value);
				$name = ucwords($name);

				if (!isset($template_cats[$cat_value]))
				{
					$template_cats[$cat_value]['count'] = 1;
				}
				else
				{
					$template_cats[$cat_value]['count']++;
				}

				$template_cats[$cat_value]['value'] = $cat_value;
				$template_cats[$cat_value]['label'] = "$name";
			}
		}

		return $template_cats;
	}
	
	/**
	 *  Get's template and extension setting data
	 *  
	 *  @retuns ARRAY of template & extension data
	 */
	public static function get_extended_data() {
		global $lp_data;
		
		$lp_data = apply_filters( 'lp_extension_data' , $lp_data);
		
		return $lp_data;
	}
	

}

new Landing_Pages_Load_Extensions;

/* Get data array of template settings */
function lp_get_extension_data() {
	return Landing_Pages_Load_Extensions::get_extended_data();	
}





    public static function get_variations( $landing_page_id ) {
        if (!$landing_page_id) {
            return array();
        }

        if (!is_array($variations)) {
            $variations = explode( ',' , $variations );
        }


    width: 20px;

    color: red;

    display: block;
    color: grey;
    font-size: 10px;
    font-style: italic;

    padding: 10px;
    padding-left: 4px;
    padding-top: 6px;

    margin-left: 12px;
    color: red;
    font-size: 12px;
    margin-right: 8px;

    display: inline-block;

    font-size: 11px;
    position: absolute;
    font-weight: 100;
    right: 10px;
    top: 3px;
.lp-pop-edit a {
    color: #fff;
    color: green;
    font-size: 14px;
    font-weight: bold;
    text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5);
    color: red;
    font-size: 12px;
    display: inline-block !important;
    margin-right: 11px !important;
    margin-left: 5px !important;
    color: #333;
    text-decoration: none;
.qtip-titlebar {
    position: relative;
    padding: 0px;
.qtip-jtools {
    border: 2px solid rgba(172, 172, 172, 1);
    position: relative;
    margin: 0 0 5px;
    padding: 12px 17px 14px 14px;
    line-height: 19px;
    font-size: 19px;
    color: #fff;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
    background: #8cc1e9;
    background-image: -webkit-gradient(linear, left bottom, left top, from(#72a7cf), to(#8cc1e9));
    background-image: -webkit-linear-gradient(bottom, #72a7cf, #8cc1e9);
    background-image: -moz-linear-gradient(bottom, #72a7cf, #8cc1e9);
    background-image: -o-linear-gradient(bottom, #72a7cf, #8cc1e9);
    background-image: linear-gradient(to top, #72a7cf, #8cc1e9);

    padding: 6px 20px;
    margin: 0;
    font-size: 13px;
    vertical-align: top;
    padding-left: 5px;
    padding-right: 5px;
.stats li:hover {
    background: #e0e0e0;
    padding-top: 0px;
    margin-left: 4px;
    position: absolute;
    border: 1px solid #EBEBEA;
    padding-right: 0px;
.lp-current-winner {
    background-color: rgb(226, 255, 201);
    text-align: center;
    float: none;
    font-weight: normal;
    color: rgb(117, 117, 117) !important;
.wp-list-table td.impressions, .wp-list-table td.actions, .wp-list-table td.cr {
    margin: 0;
    text-align: center;
    padding-top: 15px;
    border-right: 1px solid #EBEBEA;
    font-size: 15px !important;
    margin-top: 2px !important;
    display: inline-block;

.post-state .states {
    font-size: 10px;
    padding: 3px 8px 3px 8px;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
}

.post-state .password {
    background: #000;
    color: #fff;
}

.post-state .pending {
    background: #83CF21 !important;
    color: #fff;
}

.post-state .private {
    background: #E0A21B;
    color: #fff;
}

.post-state .draft {
    background: #006699;
    color: #fff;
}

    color: #21759b;
    font-size: 9px;
    padding-left: 10px;
.stats li:last-child {
    padding-left: 7px;
    padding-top: 6px;
    color: #777;
    font-size: 11px;
    display: none;
    font-size: 12px;
    border-top: none;
    width: 100%;
    border-bottom: none;
    margin-bottom: -2px;
    padding-bottom: 0px;
    display: inline-block;
    margin-top: 0px;

    font-size: 13px;
    min-width: 199px;
    display: inline-block;

    visibility: visible;
}

    display: inline-block;
    text-align: center;
    min-width: 30px;
    padding-right: 5px;
    padding-left: 5px;
    display: inline-block;
    padding-left: 10px;
    color: #ccc;
    font-weight: bold;
    font-size: 19px;
    display: inline-block;
    min-width: 60px;
    display: inline-block;
    padding-left: 4px;
    padding-right: 4px;
    display: inline-block;

    font-size: 20px;
    min-width: 16px;
    min-height: 20px;
    border-radius: 3px;
    background: #f3f3f3;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#fefefe), to(#f4f4f4));
    background-image: -webkit-linear-gradient(top, #fefefe, #f4f4f4);
    background-image: -moz-linear-gradient(top, #fefefe, #f4f4f4);
    background-image: -o-linear-gradient(top, #fefefe, #f4f4f4);
    background-image: linear-gradient(to bottom, #fefefe, #f4f4f4);
    border-color: #bbb;
    color: #333;
    text-shadow: 0 1px 0 #fff;
    font-family: sans-serif;
    cursor: pointer;
    border-width: 1px;
    border-style: solid;
    padding: 1px;
    padding-left: 4px;
    text-align: center;
    padding-right: 5px;
    padding-top: 6px;
    margin-right: 5px;
    background-image: -webkit-gradient(linear, left top, left bottom, from(#2a95c5), to(#21759b));
    background-image: -webkit-linear-gradient(top, #2a95c5, #21759b);
    background-image: -moz-linear-gradient(top, #2a95c5, #21759b);
    background-image: -ms-linear-gradient(top, #2a95c5, #21759b);
    background-image: -o-linear-gradient(top, #2a95c5, #21759b);
    background-image: linear-gradient(to bottom, #2a95c5, #21759b);
    border-color: #21759b;
    border-bottom-color: #1e6a8d;
    -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5);
    box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.5);
    color: #fff;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
    font-weight: normal;
    margin-right: 0px !important;

    font-weight: normal !important;
    color: #ccc;
    box-shadow: none;
    -webkit-box-shadow: none;

a.cr-number:hover {
    background-image: -webkit-gradient(linear, left top, left bottom, from(#2e9fd2), to(#21759b));
    background-image: -webkit-linear-gradient(top, #2e9fd2, #21759b);
    background-image: -moz-linear-gradient(top, #2e9fd2, #21759b);
    background-image: -ms-linear-gradient(top, #2e9fd2, #21759b);
    background-image: -o-linear-gradient(top, #2e9fd2, #21759b);
    background-image: linear-gradient(to bottom, #2e9fd2, #21759b);
    border-color: #1b607f;
    -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6);
    box-shadow: inset 0 1px 0 rgba(120, 200, 230, 0.6);
    color: #fff;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3);
}
Version: 1.8.8
			define('LANDINGPAGES_CURRENT_VERSION', '1.8.8' );

        }
			if ($current_variation_id>0) {
                foreach($wpdb->last_result as $k => $v){
                    $data[$v->meta_key] =   $v->meta_value;
                };
                //echo $len;exit;
                foreach ($data as $key=>$value)
                {
                    if (substr($key,-$len)==$suffix)
                    {
                        delete_post_meta($post__ID, $key, $value);
                    }
                }

                $_GET['lp-variation-id'] = $current_variation_id;
            }

            //check for pause command
            if (isset($_GET['ab-action'])&&$_GET['ab-action']=='pause-variation')
            {
                if ($_GET['lp-variation-id']==0)
                {
                    update_post_meta( $post->ID , 'lp_ab_variation_status' , '0' );
                }
                else
                {
                    update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '0');
                }
            }

            //check for pause command
            if (isset($_GET['ab-action'])&&$_GET['ab-action']=='play-variation')
            {
                if ($_GET['lp-variation-id']==0)
                {
                    update_post_meta( $post->ID , 'lp_ab_variation_status' , '1' );
                }
                else
                {
                    update_post_meta( $post->ID , 'lp_ab_variation_status-'.$_GET['lp-variation-id'] , '1');
                }
            }

            //return;

            (isset($_GET['new-variation'])&&$_GET['new-variation']==1) ? $new_variation = 1 : $new_variation = 0;

            $content_area = lp_content_area($post,null,true);

            //prepare for new variation creation - use A as default content if not being cloned
            if (($new_variation==1&&!isset($_GET['clone']))||isset($_GET['clone'])&&$_GET['clone']==0)
            {
                $content_area = get_post_field('post_content', $_GET['post']);
                $content_area = wpautop($content_area);
            }
            else if ($new_variation==1&&isset($_GET['clone']))
            {
                $content_area = get_post_field('content-'.$_GET['clone'], $_GET['post']);
                $content_area = wpautop($content_area);
            }

            //if new variation and cloning then programatically prepare the next variation id
            if($new_variation==1&&isset($_GET['clone']))
            {
                $array_variations = explode(',',$variations);
                sort($array_variations,SORT_NUMERIC);

                $lid = end($array_variations);
                $current_variation_id = $lid+1;

                $_SESSION['lp_ab_test_open_variation'] = $current_variation_id;
            }
            //echo $current_variation_id;exit;
            //enqueue and localize scripts
            wp_enqueue_style('lp-ab-testing-admin-css', LANDINGPAGES_URLPATH . 'css/admin-ab-testing.css');
            wp_enqueue_script('lp-ab-testing-admin-js', LANDINGPAGES_URLPATH . 'js/admin/admin.post-edit-ab-testing.js', array( 'jquery' ));
            wp_localize_script( 'lp-ab-testing-admin-js', 'variation', array( 'pid' => $_GET['post'], 'vid' => $current_variation_id  , 'new_variation' => $new_variation  , 'variations'=> $variations  , 'content_area' => $content_area  ));

        }

    }

    /* force visual editor to open in text mode */

    function lp_ab_testing_force_default_editor() {
        //allowed: tinymce, html, test
        return 'html';
    }

    add_filter('lp_edit_main_headline','lp_ab_testing_admin_prepare_headline');
    function lp_ab_testing_admin_prepare_headline($main_headline)
    {

        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if (isset($_REQUEST['post']))
        {
            $post_id = $_REQUEST['post'];
        }
        else if (isset($_REQUEST['lp_id']))
        {
            $post_id = $_REQUEST['lp_id'];
        }

        //return "hello";

        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
        {
            $main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
        }
        else if (isset($_GET['clone'])&&$_GET['clone']>0)
        {
            $main_headline = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
        }

        if (!$main_headline&&isset($_REQUEST['post']))
        {
            get_post_meta($_REQUEST['post'],'lp-main-headline', true);
        }

        return $main_headline;
    }

    //disable this because it will populate all wp_editor isntances rather than targeted instances
    //add_filter('the_editor_content', 'lp_ab_testing_the_editor_content');
    function lp_ab_testing_the_editor_content($content) {
        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if (isset($_REQUEST['post']))
        {
            $post_id = $_REQUEST['post'];
        }
        else if (isset($_REQUEST['lp_id']))
        {
            $post_id = $_REQUEST['lp_id'];
        }

        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
        {
            $content = get_post_field('content-'.$current_variation_id, $post_id);
        }
        else if (isset($_GET['clone']))
        {
            $content = get_post_meta($post_id,'lp-main-headline-'.$_GET['clone'], true);
        }

        return $content;
    }


    add_filter('lp_edit_variation_notes','lp_ab_testing_admin_prepare_notes');
    function lp_ab_testing_admin_prepare_notes($variation_notes)
    {
        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if (isset($_REQUEST['post']))
        {
            $post_id = $_REQUEST['post'];
        }
        else if (isset($_REQUEST['lp_id']))
        {
            $post_id = $_REQUEST['lp_id'];
        }

        //return "hello";

        if ($current_variation_id>0&&!isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
        {
            $variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$current_variation_id, true);
        }
        else if (isset($_GET['clone'])&&$_GET['clone']>0)
        {
            $variation_notes = get_post_meta($post_id,'lp-variation-notes-'.$_GET['clone'], true);
        }

        if (!$variation_notes&&isset($_REQUEST['post']))
        {
            get_post_meta($_REQUEST['post'],'lp-variation-notes', true);
        }

        return $variation_notes;
    }

    add_filter('lp_selected_template_id','lp_ab_testing_prepare_id');//prepare name id for hidden selected template input
    add_filter('lp_display_headline_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
    add_filter('lp_display_notes_input_id','lp_ab_testing_prepare_id');//prepare id for main headline in template customizer mode
    function lp_ab_testing_prepare_id($id)
    {
        $current_variation_id = lp_ab_testing_get_current_variation_id();

        //check if variation clone is initiated
        if (isset($_GET['new_meta_key']))
            $current_variation_id = $_GET['new_meta_key'];

        if ($current_variation_id>0)
        {
            $id = $id.'-'.$current_variation_id;
        }

        return $id;
    }

    //prepare id for wp_editor in template customizer
    add_filter('lp_wp_editor_id','lp_ab_testing_prepare_wysiwyg_editor_id');
    function lp_ab_testing_prepare_wysiwyg_editor_id($id)
    {
        $current_variation_id = lp_ab_testing_get_current_variation_id();
        //echo $current_variation_id;exit;
        if ($current_variation_id>0)
        {
            switch ($id) {
                case "wp_content":
                    $id = 'content-'.$current_variation_id;
                    break;
                case "lp-conversion-area":
                    $id = 'landing-page-myeditor-'.$current_variation_id;
                    break;
                default:
                    $id = $id.'-'.$current_variation_id;
            }

        }

        return $id;
    }


    add_filter('lp_show_metabox','lp_ab_testing_admin_prepare_meta_ids', 5, 2);
    function lp_ab_testing_admin_prepare_meta_ids($lp_custom_fields, $main_key)
    {
        if (isset($_REQUEST['new-variation'])&&!isset($_REQUEST['clone']))
        {
            return $lp_custom_fields;
        }

        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if (isset($_GET['clone'])) {
            $current_variation_id = $_GET['clone'];
        }

        if ($current_variation_id>0)
        {
            $post_id = $_GET['post'];
            foreach ($lp_custom_fields as $key=>$field)
            {
                $default = get_post_meta($post_id, $field['id'], true);

                $id = $field['id'];
                $field['id'] = $id.'-'.$current_variation_id ;

                if ($default) {
                    $field['default'] = $default;
                }

                $lp_custom_fields[$key] = $field;
            }
            return $lp_custom_fields;
        }

        //print_r($lp_custom_fields);exit;
        return $lp_custom_fields;
    }

    add_filter('lp_variation_selected_template','lp_ab_testing_lp_variation_selected_template', 10, 2);
    function lp_ab_testing_lp_variation_selected_template($selected_template, $post)
    {
        if (isset($_GET['new-variation']))
            return $selected_template;

        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if ($current_variation_id>0)
        {
            $selected_template = get_post_meta( $post->ID , 'lp-selected-template-'.$current_variation_id , true);
        }

        //print_r($lp_custom_fields);exit;
        return $selected_template;
    }

    //add filter to modify thumbnail preview
    add_filter('lp_live_screenshot_url', 'lp_ab_testing_prepare_screenshot');
    function lp_ab_testing_prepare_screenshot($link)
    {
        $variation_id = lp_ab_testing_get_current_variation_id();
        $link = $link."?lp-variation-id=".$variation_id;
        return $link;
    }



    add_filter("post_type_link", "lp_ab_append_variation_id_to_adminbar_link", 10,2);
    function lp_ab_append_variation_id_to_adminbar_link($link, $post)
    {
        if( $post->post_type == 'landing-page' )
        {
            $current_variation_id = lp_ab_testing_get_current_variation_id();

            if ($current_variation_id>0)
                $link = $link."?lp-variation-id=".$current_variation_id;
        }

        return $link;
    }

    if(!defined('AUTOSAVE_INTERVAL')) {
        define('AUTOSAVE_INTERVAL', 86400);
    }
    function lp_ab_testing_wp_insert_post_data($data,$postarr)
    {

        //exit;
        //$variation_id = lp_ab_testing_get_current_variation_id();
        //echo $variation_id;exit;
        if (isset($postarr['lp-variation-id'])&&$postarr['lp-variation-id']>0)
        {
            $postarr = array();
            $data = array();

            remove_action('save_post','lp_save_meta',10);
            remove_action('save_post','lp_ab_testing_save_post',10);

            $postID = $_POST['post_ID'];
            if($parent_id = wp_is_post_revision($_POST['post_ID']))
            {
                $postID = $parent_id;
            }

            lp_ab_testing_save_post($postID);

        }
        else
        {
            //echo "here";exit;
            //$this_data = json_encode($data);
            //mail('hudson.atwell@gmail.com','test2',$this_data);
        }

        if (count($data)>1)
            return $data;
    }

    add_action('save_post','lp_ab_testing_save_post');
    function lp_ab_testing_save_post($postID)
    {
        global $post;

        $var_final = (isset($_POST['lp-variation-id'])) ? $_POST['lp-variation-id'] : '0';
        if (  isset($_POST['post_type']) && $_POST['post_type']=='landing-page')
        {
            if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||$_POST['post_type']=='revision')
            {
                return;
            }

            if($parent_id = wp_is_post_revision($postID))
            {
                $postID = $parent_id;
            }


            $this_variation = $var_final;
            //echo $this_variation;
            //print_r($_POST);exit;

            //first add to varation list if not present.
            $variations = get_post_meta($postID,'lp-ab-variations', true);
            if ($variations)
            {
                $array_variations = explode(',',$variations);
                if (!in_array($this_variation,$array_variations))
                {
                    $array_variations[] = $this_variation;
                }
            }
            else
            {
                if  ($this_variation>0)
                {
                    $array_variations[] = 0;
                    $array_variations[] = $this_variation;
                }
                else
                {
                    $array_variations[] = $this_variation;
                }
            }

            //print_r($array_variations);exit;
            //update_post_meta($postID,'lp-ab-variations', "");
            update_post_meta($postID,'lp-ab-variations', implode(',',$array_variations));
            //add_post_meta($postID, 'lp_ab_variation_status-'.$this_variation , 1);

            //echo $this_variation;exit;
            if ($this_variation==0)
            {
                return;
            }
            //echo $this_variation;exit;
            //print_r($_POST);

            //next alter all custom fields to store correct varation and create custom fields for special inputs
            $ignore_list = array('post_status','post_type','tax_input','post_author','user_ID','post_ID','catslist','post_title','samplepermalinknonce',
                'autosavenonce','action','autosave','mm','jj','aa','hh','mn','ss','_wp_http_referer','lp-variation-id','_wpnonce','originalaction','original_post_status',
                'referredby','_wp_original_http_referer','meta-box-order-nonce','closedpostboxesnonce','hidden_post_status','hidden_post_password','hidden_post_visibility','visibility',
                'post_password','hidden_mm','cur_mm','hidden_jj','cur_jj','hidden_aa','cur_aa','hidden_hh','cur_hh','hidden_mn','cur_mn','original_publish','save','newlanding_page_category','newlanding_page_category_parent',
                '_ajax_nonce-add-landing_page_category','lp_lp_custom_fields_nonce','lp-selected-template','post_mime_type','ID','comment_status','ping_status');

            //$special_list = array('content','post-content');
            //print_r($_POST);exit;
            //echo $this_variation;exit;
            foreach ($_POST as $key=>$value)
            {
                //echo $key." : -{$this_variation} : $value<br>";
                if (!in_array($key,$ignore_list)&&!strstr($key,'nonce'))
                {
                    if ($key=='post_content')
                        $key = 'content';

                    if (!strstr($key,"-{$this_variation}"))
                    {
                        $new_array[$key.'-'.$this_variation] = $value;
                    }
                    else
                    {
                        //echo $key." : -{$this_variation}<br>";
                        $new_array[$key] = $value;
                    }
                }
                //echo $key." : -{$this_variation} : $value<br>";
            }

            //print_r($new_array);exit;

            foreach($new_array as $key => $val)
            {
                $old = get_post_meta($postID, $key, true);
                $new = $val;
                //echo "$key  : $old v. $new <br>";
                //if (isset($new) && $new != $old ) {
                update_post_meta($postID, $key, $new);
                //} elseif ('' == $new && $old) {
                //delete_post_meta($postID, $key, $old);
                //}
            }

        }
    }
    //prepare customizer meta data for ab varations
    add_filter('lp_get_value','lp_ab_testing_prepare_variation_meta', 1 , 4);
    function lp_ab_testing_prepare_variation_meta($return, $post, $key, $id)
    {
        if (isset($_REQUEST['lp-variation-id'])||isset($_COOKIE['lp-variation-id']))
        {
            (isset($_REQUEST['lp-variation-id'])) ? $variation_id = $_REQUEST['lp-variation-id'] : $variation_id = $_COOKIE['lp-variation-id'];
            if ($variation_id>0)
                return do_shortcode(get_post_meta($post->ID, $key.'-'.$id. '-' .$variation_id , true));
            else
                return $return;
        }
        else
        {
            return $return;
        }
    }

    //prepare customizer, admin, and preview links for variations
    add_filter('lp_customizer_customizer_link', 'lp_ab_append_variation_id_to_link');
    add_filter('lp_customizer_admin_bar_link', 'lp_ab_append_variation_id_to_link');
    add_filter('lp_customizer_preview_link','lp_ab_append_variation_id_to_link');

    function lp_ab_append_variation_id_to_link($link)
    {

        $current_variation_id = lp_ab_testing_get_current_variation_id();

        if ($current_variation_id>0)
            $link = $link."&lp-variation-id=".$current_variation_id;

        return $link;
    }
    global $post;
    $variation_id = lp_ab_testing_get_current_variation_id();
    if ($variation_id>0)
    {
        $content = get_post_meta($post->ID,'content-'.$variation_id, true);
        if ( !is_admin() )
        {
            $content = wpautop($content);
            $content = do_shortcode($content);
        }
    }
    return $content;
        'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O',
        'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y',
        'Z'
    );

    if (isset($alphabet[$key])) {
        return $alphabet[$key];
    }
    if ( isset($_GET['ab-action']) &&is_admin())
    {
        return $_SESSION['lp_ab_test_open_variation'];
    }

    if (!isset($_SESSION['lp_ab_test_open_variation'])&&!isset($_REQUEST['lp-variation-id']))
    {
        $current_variation_id = 0;
    }
    //echo $_REQUEST['lp-variation-id'];
    if (isset($_REQUEST['lp-variation-id']))
    {
        $_SESSION['lp_ab_test_open_variation'] = $_REQUEST['lp-variation-id'];
        $current_variation_id = $_REQUEST['lp-variation-id'];
        //echo "setting session $current_variation_id";
    }

    if (isset($_GET['message'])&&$_GET['message']==1&&isset( $_SESSION['lp_ab_test_open_variation'] ))
    {
        $current_variation_id = $_SESSION['lp_ab_test_open_variation'];

        //echo "here:".$_SESSION['lp_ab_test_open_variation'];
    }

    if (isset($_GET['ab-action'])&&$_GET['ab-action']=='delete-variation')
    {
        $current_variation_id = 0;
        $_SESSION['lp_ab_test_open_variation'] = 0;
    }

    if (!isset($current_variation_id))
        $current_variation_id = 0 ;

    return $current_variation_id;
    $current_variation_id = lp_ab_testing_get_current_variation_id();

    if (isset($post))
    {
        $post_id = $post->ID;
    }
    else if (isset($_REQUEST['post']))
    {
        $post_id = $_REQUEST['post'];
    }
    else if (isset($_REQUEST['lp_id']))
    {
        $post_id = $_REQUEST['lp_id'];
    }


    if ($current_variation_id>0)
        $content = get_post_meta($post_id,'landing-page-myeditor-'.$current_variation_id, true);

    return $content;
    $current_variation_id = lp_ab_testing_get_current_variation_id();

    if (isset($post))
    {
        $post_id = $post->ID;
    }
    else if (isset($_REQUEST['post']))
    {
        $post_id = $_REQUEST['post'];
    }
    else if (isset($_REQUEST['lp_id']))
    {
        $post_id = $_REQUEST['lp_id'];
    }

    if ($current_variation_id>0)
        $position = get_post_meta($post->ID, "{$key}-conversion-area-placement-".$current_variation_id, true);

    return $position;
    $current_variation_id = lp_ab_testing_get_current_variation_id();
    if (isset($post))
    {
        $post_id = $post->ID;
    }
    else if (isset($_REQUEST['post']))
    {
        $post_id = $_REQUEST['post'];
    }
    else if (isset($_REQUEST['lp_id']))
    {
        $post_id = $_REQUEST['lp_id'];
    }
    else if (isset($_REQUEST['post_id']))
    {
        $post_id = $_REQUEST['post_id'];
    }
    if ($current_variation_id>0)
        $main_headline = get_post_meta($post_id,'lp-main-headline-'.$current_variation_id, true);
    if (!$main_headline)
    {
        get_post_meta($post_id,'lp-main-headline', true);
    }
    return $main_headline;
    $this_path = LANDINGPAGES_PATH;
    $this_path = explode('wp-content',$this_path);
    $this_path = "wp-content".$this_path[1];

    $slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );
    //echo $slug;exit;
    $ab_testing = get_option( 'lp-main-landing-page-disable-turn-off-ab', "0");
    if($ab_testing === "0") {
        add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2",'top');
        add_rewrite_rule("$slug/([^/]*)?", $this_path."modules/module.redirect-ab-testing.php?permalink_name=$1 ",'top');
        add_rewrite_rule("landing-page=([^/]*)?", $this_path.'modules/module.redirect-ab-testing.php?permalink_name=$1','top');
    }
    add_filter('mod_rewrite_rules', 'lp_ab_testing_modify_rules', 1);
    function lp_ab_testing_modify_rules($rules)
    {
        if (!stristr($rules,'RewriteCond %{QUERY_STRING} !lp-variation-id'))
        {
            $rules_array = preg_split ('/$\R?^/m', $rules);
            if (count($rules_array)<3)
            {
                $rules_array = explode("\n", $rules);
                $rules_array = array_filter($rules_array);
            }

            //print_r($rules_array);exit;

            $this_path = LANDINGPAGES_PATH;
            $this_path = explode('wp-content',$this_path);
            $this_path = "wp-content".$this_path[1];
            $slug = get_option( 'lp-main-landing-page-permalink-prefix', 'go' );

            $i = 0;
            foreach ($rules_array as $key=>$val)
            {

                if ( stristr($val,"RewriteRule ^{$slug}/([^/]*)? ") ||  stristr($val,"RewriteRule ^{$slug}/([^/]*)/([0-9]+)/ ") )
                {
                    $new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
                    $rules_array[$i] = $new_val;
                    $i++;
                    $rules_array[$i] = $val;
                    $i++;
                }
                else
                {
                    $rules_array[$i] = $val;
                    $i++;
                }
            }

            $rules = implode("\r\n", $rules_array);
        }

        return $rules;
    }
    global $post;
    $current_variation_id = lp_ab_testing_get_current_variation_id();
    if ($current_variation_id>0)
    {
        $new_template =  get_post_meta($post->ID, 'lp-selected-template-'.$current_variation_id, true);
        if ($new_template)
            $template = $new_template;
    }
    return $template;
    $current_variation_id = lp_ab_testing_get_current_variation_id();
    //echo $current_variation_id;exit;
    if ($current_variation_id>0)
    {
        $id = $id.'-'.$current_variation_id;
    }

    return $id;
    $page_id = lp_url_to_postid( trim($_POST['current_url']) );
    $variations = get_post_meta($page_id,'lp-ab-variations', true);
    $marker = get_post_meta($page_id,'lp-ab-variations-marker', true);
    if (!is_numeric($marker)) {
        $marker = 0;
    }
    if ($variations)
    {
        //echo $variations;
        $variations = explode(',',$variations);
        //print_r($variations);
        $variation_id = $variations[$marker];
        $marker++;
        if ($marker>=count($variations))
        {
            //echo "here";
            $marker = 0;
        }
        update_post_meta($page_id, 'lp-ab-variations-marker', $marker);
        echo $variation_id;
        die();
    }
    global $post;
    if ( !isset($post) || $post->post_type != 'landing-page' ) {
        return $content;
    }
    $variation_id = lp_ab_testing_get_current_variation_id();
    if ($variation_id>0)
    {
        $content = do_shortcode(get_post_meta($post->ID,'content-'.$variation_id, true));
    }
    return $content;
    global $post;
    if (!isset($post))
        return $content;
    if ( ( $post->post_type!='landing-page'||is_admin()) || $id != $post->ID)
        return $content;
    return lp_main_headline($post, null, true);
    /* If Landing Page Post Type */
    if ( $post_type == 'landing-page' ) {
        $meta_key = 'lp-ab-variation-impressions-'.$variation_id;
    }
    /* If Non Landing Page Post Type */
    else  {
        $meta_key = '_inbound_impressions_count';
    }
    $impressions = get_post_meta($post_id, $meta_key , true);
    if (!is_numeric($impressions)) {
        $impressions = 1;
    } else {
        $impressions++;
    }
    update_post_meta($post_id, $meta_key , $impressions);
    $permalink = get_permalink( $post->ID );
    $randomstring = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 10);
    wp_enqueue_script( 'lp_ab_testing_customizer_js', LANDINGPAGES_URLPATH . 'js/customizer.ab-testing.js', array( 'jquery' ) );
    wp_localize_script( 'lp_ab_testing_customizer_js', 'ab_customizer', array( 'lp_id' => $post->ID ,'permalink' => $permalink , 'randomstring' => $randomstring));
    wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'css/customizer-ab-testing.css');
	
	return inbound_install_example_lander();
}

/**
*  Install example landing page and return landing page id
*/
function inbound_install_example_lander() {

	
	$landing_page_id = wp_insert_post(
        array(
            'post_title'     => __( 'A/B Testing Landing Page Example' , 'landing-pages'),
            'post_content'   => __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'post'),
            'post_status'    => 'publish',
            'post_type'      => 'landing-page',
            'comment_status' => 'closed'
        )
    );
	
    add_post_meta($landing_page_id, 'lp-main-headline', __( 'Main Catchy Headline (A)' , 'landing-pages') );
    add_post_meta($landing_page_id, 'lp-selected-template', 'svtle');
    add_post_meta($landing_page_id, 'svtle-conversion-area-content', '<h2>'.__( 'Form a' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]' );
    add_post_meta($landing_page_id, 'svtle-main-content', __( '<p>This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>' , 'landing-pages') );
    add_post_meta($landing_page_id, 'lp-main-headline-1', __('Main Catchy Headline Two (B)' , 'landing-pages') );
    add_post_meta($landing_page_id, 'lp-selected-template-1', 'svtle');
    add_post_meta($landing_page_id, 'svtle-conversion-area-content-1', '<h2>'.__( 'Form B' , 'landing-pages') .'</h2>[inbound_forms id="default_1" name="First, Last, Email Form"]');
    add_post_meta($landing_page_id, 'svtle-main-content-1', '<p>(Version B) This is the first paragraph of your landing page where you want to draw the viewers in and quickly explain your value proposition.</p><p><strong>Use Bullet Points to:</strong><ul><li>Explain why they should fill out the form</li><li>What they will learn if they download</li><li>A problem this form will solve for them</li></ul></p><p>Short ending paragraph reiterating the value behind the form</p>');
    add_post_meta($landing_page_id, 'lp-ab-variations', '0,1');
    add_post_meta($landing_page_id, 'lp-ab-variation-impressions-0', 30);
    add_post_meta($landing_page_id, 'lp-ab-variation-impressions-1', 35);
    add_post_meta($landing_page_id, 'lp-ab-variation-conversions-0', 10);
    add_post_meta($landing_page_id, 'lp-ab-variation-conversions-1', 15);
    add_post_meta($landing_page_id, 'svtle-submit-button-color', '5baa1e');
    add_post_meta($landing_page_id, 'svtle-display-social', '0');
    add_post_meta($landing_page_id, 'svtle-logo', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
    add_post_meta($landing_page_id, 'svtle-body-color', 'ffffff');
    add_post_meta($landing_page_id, 'svtle-sidebar', 'left');
    add_post_meta($landing_page_id, 'svtle-page-text-color', '4d4d4d');
    add_post_meta($landing_page_id, 'svtle-sidebar-color', 'ffffff');
    add_post_meta($landing_page_id, 'svtle-sidebar-text-color', '000000');
    add_post_meta($landing_page_id, 'svtle-header-color', 'ffffff');
    add_post_meta($landing_page_id, 'svtle-submit-button-color-1', 'ff0c00');
    add_post_meta($landing_page_id, 'svtle-display-social-1', '0');
    add_post_meta($landing_page_id, 'svtle-logo-1', '/wp-content/plugins/landing-pages/templates/svtle/assets/images/inbound-logo.png');
    add_post_meta($landing_page_id, 'svtle-body-color-1', '51b0ef');
    add_post_meta($landing_page_id, 'svtle-sidebar-1', 'left');
    add_post_meta($landing_page_id, 'svtle-page-text-color-1', '000000');
    add_post_meta($landing_page_id, 'svtle-sidebar-color-1', '51b0ef');
    add_post_meta($landing_page_id, 'svtle-sidebar-text-color-1', '000000');
    add_post_meta($landing_page_id, 'svtle-header-color-1', '51b0ef');
        "default_landing_page" => $landing_page_id
	
    update_option( "lp_settings_general" , $options );
    return $landing_page_id;
        /*  array(
              'name'                  => 'TGM Example Plugin', // The plugin name
              'slug'                  => 'tgm-example-plugin', // The plugin slug (typically the folder name)
              'source'                => get_stylesheet_directory() . '/lib/plugins/tgm-example-plugin.zip', // The plugin source
              'required'              => true, // If false, the plugin is only 'recommended' instead of required
              'version'               => '', // E.g. 1.0.0. If set, the active plugin must be this version or higher, otherwise a notice is presented
              'force_activation'      => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch
              'force_deactivation'    => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins
              'external_url'          => '', // If set, overrides default API URL and points to an external URL
          ), */
        array(
            'name'      => __('WordPress Calls to Action' , 'landing-pages') .' <span class=\'inbound-install-notice\'> - '. __('This <b>free</b> landing page addon will drive more traffic into your Landing Pages with Targeted Calls to Action in your sites sidebars & content. Create popups to capture visitor attention and convert more leads.' , 'landing-pages') . ' <a class=\'inbound-install-notice-links\' href=\'http://wordpress.org/plugins/cta/\'> ' . __('Learn more about WordPress Calls to Action' , 'landing-pages') . '</a></span>',
            'slug'      => 'cta',
            'required'  => false,
        ),
            // %1$s = dashboard link
<phpunit bootstrap="tests/phpunit/bootstrap.php" backupGlobals="false" colors="true">
            <directory prefix="test." suffix=".php">tests/phpunit/</directory>
Stable Tag: 1.8.8
= 1.8.8 =
* Security Patch for XSS in firefox

    background-image: url('../../images/global/shortcodes-blue.png');
    background-repeat: no-repeat;
    background-position: 0.15em 50%;
    padding-left: 22px;

    padding-left: 5px;

.inbound-nav-marketing div:first-of-type {
    color: rgba(240, 245, 250, 1);

    display: none;

.switch-versions, .switch-versions {

    color: #ff9900;
    content: '• ';

    width: 140px;

    color: #21759b !important;
    text-shadow: none;

    background-color: #fff;
    height: 18px;
    line-height: 18px;
    padding: 1px 4px;

    -webkit-border-radius: 11px;
    -moz-border-radius: 11px;
    border-radius: 11px;
    font-size: 0.67em;
    margin: 0 0 0 2px;

    font-family: 'FontAwesome';
    src: url('../../fonts/fontawesome/fontawesome-webfont.eot');
    src: url('../../fonts/fontawesome/fontawesome-webfont.eot') format('embedded-opentype'),
    url('../../fonts/fontawesome/fontawesome-webfont.woff?v=3.0.2') format('woff'),
    url('../../fonts/fontawesome/fontawesome-webfont.ttf?v=3.0.2') format('truetype');
    font-weight: normal;
    font-style: normal;

    font-family: "FontAwesome" !important;
    content: "\f0c0";

    display: none;

#adminmenu .menu-icon-wp-lead div.wp-menu-image img {
    display: none;

    display: block;

    padding-left: 30px !important;

    color: #2ea2cc;

    padding-left: 31px !important;

    max-height: 22px !important;
    padding: 0px !important;
    min-height: 23px !important;
    padding-left: 3px !important;
    margin-bottom: 1px !important;
}

#wp-admin-bar-inbound-docs-searchform, #wp-admin-bar-inbound-leads-search {
    margin-bottom: 10px !important;

#wp-admin-bar-inbound-cta .ab-submenu a, #wp-admin-bar-inbound-leads .ab-submenu a, #wp-admin-bar-inbound-landingpages .ab-submenu a, #wp-admin-bar-inbound-forms .ab-submenu a, #wp-admin-bar-inbound-templates .ab-submenu a, #wp-admin-bar-inbound-analytics .ab-submenu a, #wp-admin-bar-inbound-seo .ab-submenu a {
    padding-left: 10px !important;
}

#wp-admin-bar-inbound-cta:before, #wp-admin-bar-inbound-leads:before, #wp-admin-bar-inbound-landingpages:before, #wp-admin-bar-inbound-forms:before, #wp-admin-bar-inbound-templates:before, #wp-admin-bar-inbound-settings:before, #wp-admin-bar-inbound-analytics:before, #wp-admin-bar-inbound-seo:before {
    font-family: "FontAwesome" !important;
    content: "\f05b" !important;
    font: 100 19px/1 "FontAwesome" !important;
    padding-top: 4px;
    width: 30px;
    display: inline-block;
    height: 30px;
    position: absolute;
    left: 6px;
}

    content: "\f0c0" !important;
    font: 100 17px/1 "FontAwesome" !important;

    content: "\f15c" !important;
    left: 7px;
    font-size: 21px !important;
}

    font: 400 18px/1 dashicons !important;
}

}

    content: "\f013" !important;
    left: 7px !important;

    content: "\f012" !important;
    font-size: 17px !important;

    content: "\f002" !important;
    font-size: 17px !important;

    vertical-align: top;

    font-family: "FontAwesome" !important;
    content: "\f05b";
    font: 400 24px/1 "FontAwesome" !important;
    padding-top: 6px;

    position: absolute;
    top: 0;
    left: 0;
    width: 22px;
}

.inbound-form-shortcode input {
    overflow:hidden;
}
.inbound-form-shortcode  {
    overflow:hidden;
				$form_id = (isset($_GET['post']) && is_int( $_GET['post'] )) ? $_GET['post'] : ''; 
		    <?php

            if (defined('INBOUND_PRO_PATH')) {
            ?>
            <h3><?php _e( 'Inbound Pro Users' , INBOUNDNOW_TEXT_DOMAIN ); ?></h3>
            <div class='' style='padding-left:20px;'>

                <?php echo sprintf( __( ' Membership holders should ignore the setup area below and referrer to %s this document %s for instructions on setting up a followup email. We are leaveing this section in up for non members and for members that are leveraging it. We may remove it remove it entirely from the Inbound Pro plugin. ' , INBOUNDNOW_TEXT_DOMAIN ) , '<a href="http://docs.inboundnow.com/guide/creating-a-follow-up-email-using-inbound-now-as-an-autoresponder-marketing-automation/">', '</a>') ; ?>
            </div>
            <br>
            <?php
            }
            ?>

							    if ( isset($_REQUEST['post']) && is_int($_REQUEST['post'])  ) {
input[type="text"], input[type="email"], #inbound-form-wrapper input[type=text], #inbound-form-wrapper input[type=url], #inbound-form-wrapper input[type=email], #inbound-form-wrapper input[type=tel], #inbound-form-wrapper input[type=number], #inbound-form-wrapper input[type=password] , #inbound-form-wrapper select {
<IfModule mod_php5.c>
  AddType application/x-httpd-php .php .phtml .php5
  AddType application/x-httpd-php-source .phps
</IfModule>
LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
phantomjs --webdriver=4444
<VirtualHost *:80>
	ServerAdmin tests@inboundnow.com
	DocumentRoot /var/www/inboundtesting.dev/
	ServerName inboundtesting.dev
	ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
	
	# Wire up Apache to use Travis CI's php-fpm.
	<IfModule mod_fastcgi.c>
		AddHandler php5-fcgi .php
		Action php5-fcgi /php5-fcgi
		Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
		FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
	</IfModule>
  
	<Directory "/var/www/inboundtesting.dev/">
		Options FollowSymLinks MultiViews ExecCGI
		AllowOverride All
		Order deny,allow
		Allow from all
	</Directory>
</VirtualHost>
  
<?php

/* load wp */
require '../../../wp-load.php';
require '../../../wp-admin/includes/plugin.php';

/* load required landing pages files */
include_once LANDINGPAGES_PATH . 'modules/module.install.php';
include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';
/* Replace this file with actual dump of your database */
<?php
namespace Codeception\Module;

// here you can define custom actions
// all public methods declared in helper class will be available in $I

class AcceptanceHelper extends \Codeception\Module
{

}
<?php
namespace Codeception\Module;

// here you can define custom actions
// all public methods declared in helper class will be available in $I

class FunctionalHelper extends \Codeception\Module
{

}
<?php
namespace Codeception\Module;

// here you can define custom actions
// all public methods declared in helper class will be available in $I

class UnitHelper extends \Codeception\Module
{

}
# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver
        - AcceptanceHelper
        - Asserts
    config:
        WebDriver:
            url: 'http://local.wordpress.dev/'
            browser: firefox
            clear_cookies: false
            window_size: 1024x768
        PhpBrowser:
            url: 'http://inboundsoon.dev'
<?php //[STAMP] 2d5aa64986f8f94bc0f812d88aa9dee6

// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile


use Codeception\Module\PhpBrowser;
use Codeception\Module\AcceptanceHelper;

/**
 * Inherited Methods
 * @method void wantToTest($text)
 * @method void wantTo($text)
 * @method void execute($callable)
 * @method void expectTo($prediction)
 * @method void expect($prediction)
 * @method void amGoingTo($argumentation)
 * @method void am($role)
 * @method void lookForwardTo($achieveValue)
 * @method void comment($description)
 * @method void haveFriend($name, $actorClass = null)
 *
 * @SuppressWarnings(PHPMD)
*/
class AcceptanceTester extends \Codeception\Actor
{
   
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Sets the HTTP header to the passed value - which is used on
     * subsequent HTTP requests through PhpBrowser.
     *
     * Example:
     * ```php
     * <?php
     * $I->setHeader('X-Requested-With', 'Codeception');
     * $I->amOnPage('test-headers.php');
     * ?>
     * ```
     *
     * @param string $name the name of the request header
     * @param string $value the value to set it to for subsequent
     *        requests
     * @see \Codeception\Module\PhpBrowser::setHeader()
     */
    public function setHeader($name, $value) {
        return $this->scenario->runStep(new \Codeception\Step\Action('setHeader', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Deletes the header with the passed name.  Subsequent requests
     * will not have the deleted header in its request.
     *
     * Example:
     * ```php
     * <?php
     * $I->setHeader('X-Requested-With', 'Codeception');
     * $I->amOnPage('test-headers.php');
     * // ...
     * $I->deleteHeader('X-Requested-With');
     * $I->amOnPage('some-other-page.php');
     * ?>
     * ```
     * 
     * @param string $name the name of the header to delete.
     * @see \Codeception\Module\PhpBrowser::deleteHeader()
     */
    public function deleteHeader($name) {
        return $this->scenario->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Authenticates user for HTTP_AUTH
     *
     * @param $username
     * @param $password
     * @see \Codeception\Module\PhpBrowser::amHttpAuthenticated()
     */
    public function amHttpAuthenticated($username, $password) {
        return $this->scenario->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Opens the page for the given relative URI.
     *
     * ``` php
     * <?php
     * // opens front page
     * $I->amOnPage('/');
     * // opens /register page
     * $I->amOnPage('/register');
     * ?>
     * ```
     *
     * @param $page
     * @see \Codeception\Module\PhpBrowser::amOnPage()
     */
    public function amOnPage($page) {
        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Open web page at the given absolute URL and sets its hostname as the base host.
     *
     * ``` php
     * <?php
     * $I->amOnUrl('http://codeception.com');
     * $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
     * ?>
     * ```
     * @see \Codeception\Module\PhpBrowser::amOnUrl()
     */
    public function amOnUrl($url) {
        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Changes the subdomain for the 'url' configuration parameter.
     * Does not open a page; use `amOnPage` for that.
     *
     * ``` php
     * <?php
     * // If config is: 'http://mysite.com'
     * // or config is: 'http://www.mysite.com'
     * // or config is: 'http://company.mysite.com'
     *
     * $I->amOnSubdomain('user');
     * $I->amOnPage('/');
     * // moves to http://user.mysite.com/
     * ?>
     * ```
     *
     * @param $subdomain
     *
     * @return mixed
     * @see \Codeception\Module\PhpBrowser::amOnSubdomain()
     */
    public function amOnSubdomain($subdomain) {
        return $this->scenario->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Low-level API method.
     * If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly
     *
     * Example:
     *
     * ``` php
     * <?php
     * $I->executeInGuzzle(function (\GuzzleHttp\Client $client) {
     *      $client->get('/get', ['query' => ['foo' => 'bar']]);
     * });
     * ?>
     * ```
     *
     * It is not recommended to use this command on a regular basis.
     * If Codeception lacks important Guzzle Client methods, implement them and submit patches.
     *
     * @param callable $function
     * @see \Codeception\Module\PhpBrowser::executeInGuzzle()
     */
    public function executeInGuzzle($function) {
        return $this->scenario->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Perform a click on a link or a button, given by a locator.
     * If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
     * For buttons, the "value" attribute, "name" attribute, and inner text are searched.
     * For links, the link text is searched.
     * For images, the "alt" attribute and inner text of any parent links are searched.
     *
     * The second parameter is a context (CSS or XPath locator) to narrow the search.
     *
     * Note that if the locator matches a button of type `submit`, the form will be submitted.
     *
     * ``` php
     * <?php
     * // simple link
     * $I->click('Logout');
     * // button of form
     * $I->click('Submit');
     * // CSS button
     * $I->click('#form input[type=submit]');
     * // XPath
     * $I->click('//form/*[@type=submit]');
     * // link in context
     * $I->click('Logout', '#nav');
     * // using strict locator
     * $I->click(['link' => 'Login']);
     * ?>
     * ```
     *
     * @param $link
     * @param $context
     * @see \Codeception\Lib\InnerBrowser::click()
     */
    public function click($link, $context = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('click', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current page contains the given string.
     * Specify a locator as the second parameter to match a specific region.
     *
     * ``` php
     * <?php
     * $I->see('Logout'); // I can suppose user is logged in
     * $I->see('Sign Up','h1'); // I can suppose it's a signup page
     * $I->see('Sign Up','//body/h1'); // with XPath
     * ?>
     * ```
     *
     * @param      $text
     * @param null $selector
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::see()
     */
    public function canSee($text, $selector = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current page contains the given string.
     * Specify a locator as the second parameter to match a specific region.
     *
     * ``` php
     * <?php
     * $I->see('Logout'); // I can suppose user is logged in
     * $I->see('Sign Up','h1'); // I can suppose it's a signup page
     * $I->see('Sign Up','//body/h1'); // with XPath
     * ?>
     * ```
     *
     * @param      $text
     * @param null $selector
     * @see \Codeception\Lib\InnerBrowser::see()
     */
    public function see($text, $selector = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('see', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current page doesn't contain the text specified.
     * Give a locator as the second parameter to match a specific region.
     *
     * ```php
     * <?php
     * $I->dontSee('Login'); // I can suppose user is already logged in
     * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
     * $I->dontSee('Sign Up','//body/h1'); // with XPath
     * ?>
     * ```
     *
     * @param      $text
     * @param null $selector
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSee()
     */
    public function cantSee($text, $selector = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current page doesn't contain the text specified.
     * Give a locator as the second parameter to match a specific region.
     *
     * ```php
     * <?php
     * $I->dontSee('Login'); // I can suppose user is already logged in
     * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
     * $I->dontSee('Sign Up','//body/h1'); // with XPath
     * ?>
     * ```
     *
     * @param      $text
     * @param null $selector
     * @see \Codeception\Lib\InnerBrowser::dontSee()
     */
    public function dontSee($text, $selector = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSee', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there's a link with the specified text.
     * Give a full URL as the second parameter to match links with that exact URL.
     *
     * ``` php
     * <?php
     * $I->seeLink('Logout'); // matches <a href="#">Logout</a>
     * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
     * ?>
     * ```
     *
     * @param      $text
     * @param null $url
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeLink()
     */
    public function canSeeLink($text, $url = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeLink', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there's a link with the specified text.
     * Give a full URL as the second parameter to match links with that exact URL.
     *
     * ``` php
     * <?php
     * $I->seeLink('Logout'); // matches <a href="#">Logout</a>
     * $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
     * ?>
     * ```
     *
     * @param      $text
     * @param null $url
     * @see \Codeception\Lib\InnerBrowser::seeLink()
     */
    public function seeLink($text, $url = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeLink', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page doesn't contain a link with the given string.
     * If the second parameter is given, only links with a matching "href" attribute will be checked.
     *
     * ``` php
     * <?php
     * $I->dontSeeLink('Logout'); // I suppose user is not logged in
     * $I->dontSeeLink('Checkout now', '/store/cart.php');
     * ?>
     * ```
     *
     * @param $text
     * @param null $url
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeLink()
     */
    public function cantSeeLink($text, $url = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeLink', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page doesn't contain a link with the given string.
     * If the second parameter is given, only links with a matching "href" attribute will be checked.
     *
     * ``` php
     * <?php
     * $I->dontSeeLink('Logout'); // I suppose user is not logged in
     * $I->dontSeeLink('Checkout now', '/store/cart.php');
     * ?>
     * ```
     *
     * @param $text
     * @param null $url
     * @see \Codeception\Lib\InnerBrowser::dontSeeLink()
     */
    public function dontSeeLink($text, $url = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeLink', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that current URI contains the given string.
     *
     * ``` php
     * <?php
     * // to match: /home/dashboard
     * $I->seeInCurrentUrl('home');
     * // to match: /users/1
     * $I->seeInCurrentUrl('/users/');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
     */
    public function canSeeInCurrentUrl($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInCurrentUrl', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that current URI contains the given string.
     *
     * ``` php
     * <?php
     * // to match: /home/dashboard
     * $I->seeInCurrentUrl('home');
     * // to match: /users/1
     * $I->seeInCurrentUrl('/users/');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
     */
    public function seeInCurrentUrl($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInCurrentUrl', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URI doesn't contain the given string.
     *
     * ``` php
     * <?php
     * $I->dontSeeInCurrentUrl('/users/');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
     */
    public function cantSeeInCurrentUrl($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInCurrentUrl', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URI doesn't contain the given string.
     *
     * ``` php
     * <?php
     * $I->dontSeeInCurrentUrl('/users/');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
     */
    public function dontSeeInCurrentUrl($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInCurrentUrl', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL is equal to the given string.
     * Unlike `seeInCurrentUrl`, this only matches the full URL.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->seeCurrentUrlEquals('/');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
     */
    public function canSeeCurrentUrlEquals($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlEquals', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL is equal to the given string.
     * Unlike `seeInCurrentUrl`, this only matches the full URL.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->seeCurrentUrlEquals('/');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
     */
    public function seeCurrentUrlEquals($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlEquals', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL doesn't equal the given string.
     * Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
     *
     * ``` php
     * <?php
     * // current url is not root
     * $I->dontSeeCurrentUrlEquals('/');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
     */
    public function cantSeeCurrentUrlEquals($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlEquals', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL doesn't equal the given string.
     * Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
     *
     * ``` php
     * <?php
     * // current url is not root
     * $I->dontSeeCurrentUrlEquals('/');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
     */
    public function dontSeeCurrentUrlEquals($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlEquals', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL matches the given regular expression.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->seeCurrentUrlMatches('~$/users/(\d+)~');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
     */
    public function canSeeCurrentUrlMatches($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlMatches', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the current URL matches the given regular expression.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->seeCurrentUrlMatches('~$/users/(\d+)~');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
     */
    public function seeCurrentUrlMatches($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlMatches', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that current url doesn't match the given regular expression.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
     * ?>
     * ```
     *
     * @param $uri
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
     */
    public function cantSeeCurrentUrlMatches($uri) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlMatches', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that current url doesn't match the given regular expression.
     *
     * ``` php
     * <?php
     * // to match root url
     * $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
     * ?>
     * ```
     *
     * @param $uri
     * @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
     */
    public function dontSeeCurrentUrlMatches($uri) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlMatches', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Executes the given regular expression against the current URI and returns the first match.
     * If no parameters are provided, the full URI is returned.
     *
     * ``` php
     * <?php
     * $user_id = $I->grabFromCurrentUrl('~$/user/(\d+)/~');
     * $uri = $I->grabFromCurrentUrl();
     * ?>
     * ```
     *
     * @param null $uri
     *
     * @internal param $url
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::grabFromCurrentUrl()
     */
    public function grabFromCurrentUrl($uri = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('grabFromCurrentUrl', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the specified checkbox is checked.
     *
     * ``` php
     * <?php
     * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
     * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
     * ?>
     * ```
     *
     * @param $checkbox
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
     */
    public function canSeeCheckboxIsChecked($checkbox) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCheckboxIsChecked', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the specified checkbox is checked.
     *
     * ``` php
     * <?php
     * $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
     * $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
     * ?>
     * ```
     *
     * @param $checkbox
     * @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
     */
    public function seeCheckboxIsChecked($checkbox) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCheckboxIsChecked', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Check that the specified checkbox is unchecked.
     *
     * ``` php
     * <?php
     * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
     * ?>
     * ```
     *
     * @param $checkbox
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
     */
    public function cantSeeCheckboxIsChecked($checkbox) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCheckboxIsChecked', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Check that the specified checkbox is unchecked.
     *
     * ``` php
     * <?php
     * $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
     * $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
     * ?>
     * ```
     *
     * @param $checkbox
     * @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
     */
    public function dontSeeCheckboxIsChecked($checkbox) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCheckboxIsChecked', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given input field or textarea contains the given value. 
     * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
     *
     * ``` php
     * <?php
     * $I->seeInField('Body','Type your comment here');
     * $I->seeInField('form textarea[name=body]','Type your comment here');
     * $I->seeInField('form input[type=hidden]','hidden_value');
     * $I->seeInField('#searchform input','Search');
     * $I->seeInField('//form/*[@name=search]','Search');
     * $I->seeInField(['name' => 'search'], 'Search');
     * ?>
     * ```
     *
     * @param $field
     * @param $value
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeInField()
     */
    public function canSeeInField($field, $value) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInField', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given input field or textarea contains the given value. 
     * For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
     *
     * ``` php
     * <?php
     * $I->seeInField('Body','Type your comment here');
     * $I->seeInField('form textarea[name=body]','Type your comment here');
     * $I->seeInField('form input[type=hidden]','hidden_value');
     * $I->seeInField('#searchform input','Search');
     * $I->seeInField('//form/*[@name=search]','Search');
     * $I->seeInField(['name' => 'search'], 'Search');
     * ?>
     * ```
     *
     * @param $field
     * @param $value
     * @see \Codeception\Lib\InnerBrowser::seeInField()
     */
    public function seeInField($field, $value) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInField', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that an input field or textarea doesn't contain the given value.
     * For fuzzy locators, the field is matched by label text, CSS and XPath.
     *
     * ``` php
     * <?php
     * $I->dontSeeInField('Body','Type your comment here');
     * $I->dontSeeInField('form textarea[name=body]','Type your comment here');
     * $I->dontSeeInField('form input[type=hidden]','hidden_value');
     * $I->dontSeeInField('#searchform input','Search');
     * $I->dontSeeInField('//form/*[@name=search]','Search');
     * $I->dontSeeInField(['name' => 'search'], 'Search');
     * ?>
     * ```
     *
     * @param $field
     * @param $value
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeInField()
     */
    public function cantSeeInField($field, $value) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInField', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that an input field or textarea doesn't contain the given value.
     * For fuzzy locators, the field is matched by label text, CSS and XPath.
     *
     * ``` php
     * <?php
     * $I->dontSeeInField('Body','Type your comment here');
     * $I->dontSeeInField('form textarea[name=body]','Type your comment here');
     * $I->dontSeeInField('form input[type=hidden]','hidden_value');
     * $I->dontSeeInField('#searchform input','Search');
     * $I->dontSeeInField('//form/*[@name=search]','Search');
     * $I->dontSeeInField(['name' => 'search'], 'Search');
     * ?>
     * ```
     *
     * @param $field
     * @param $value
     * @see \Codeception\Lib\InnerBrowser::dontSeeInField()
     */
    public function dontSeeInField($field, $value) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInField', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if the array of form parameters (name => value) are set on the form matched with the
     * passed selector.
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('form[name=myform]', [
     *      'input1' => 'value',
     *      'input2' => 'other value',
     * ]);
     * ?>
     * ```
     * 
     * For multi-select elements, or to check values of multiple elements with the same name, an
     * array may be passed:
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('.form-class', [
     *      'multiselect' => [
     *          'value1',
     *          'value2',
     *      ],
     *      'checkbox[]' => [
     *          'a checked value',
     *          'another checked value',
     *      ],
     * ]);
     * ?>
     * ```
     *
     * Additionally, checkbox values can be checked with a boolean.
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('#form-id', [
     *      'checkbox1' => true,        // passes if checked
     *      'checkbox2' => false,       // passes if unchecked
     * ]);
     * ?>
     * ```
     * 
     * Pair this with submitForm for quick testing magic.
     * 
     * ``` php
     * <?php
     * $form = [
     *      'field1' => 'value',
     *      'field2' => 'another value',
     *      'checkbox1' => true,
     *      // ...
     * ];
     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
     * // $I->amOnPage('/path/to/form-page') may be needed
     * $I->seeInFormFields('//form[@id=my-form]', $form);
     * ?>
     * ```
     * 
     * @param $formSelector
     * @param $params
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeInFormFields()
     */
    public function canSeeInFormFields($formSelector, $params) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInFormFields', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if the array of form parameters (name => value) are set on the form matched with the
     * passed selector.
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('form[name=myform]', [
     *      'input1' => 'value',
     *      'input2' => 'other value',
     * ]);
     * ?>
     * ```
     * 
     * For multi-select elements, or to check values of multiple elements with the same name, an
     * array may be passed:
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('.form-class', [
     *      'multiselect' => [
     *          'value1',
     *          'value2',
     *      ],
     *      'checkbox[]' => [
     *          'a checked value',
     *          'another checked value',
     *      ],
     * ]);
     * ?>
     * ```
     *
     * Additionally, checkbox values can be checked with a boolean.
     * 
     * ``` php
     * <?php
     * $I->seeInFormFields('#form-id', [
     *      'checkbox1' => true,        // passes if checked
     *      'checkbox2' => false,       // passes if unchecked
     * ]);
     * ?>
     * ```
     * 
     * Pair this with submitForm for quick testing magic.
     * 
     * ``` php
     * <?php
     * $form = [
     *      'field1' => 'value',
     *      'field2' => 'another value',
     *      'checkbox1' => true,
     *      // ...
     * ];
     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
     * // $I->amOnPage('/path/to/form-page') may be needed
     * $I->seeInFormFields('//form[@id=my-form]', $form);
     * ?>
     * ```
     * 
     * @param $formSelector
     * @param $params
     * @see \Codeception\Lib\InnerBrowser::seeInFormFields()
     */
    public function seeInFormFields($formSelector, $params) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInFormFields', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if the array of form parameters (name => value) are not set on the form matched with
     * the passed selector.
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('form[name=myform]', [
     *      'input1' => 'non-existent value',
     *      'input2' => 'other non-existent value',
     * ]);
     * ?>
     * ```
     * 
     * To check that an element hasn't been assigned any one of many values, an array can be passed
     * as the value:
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('.form-class', [
     *      'fieldName' => [
     *          'This value shouldn\'t be set',
     *          'And this value shouldn\'t be set',
     *      ],
     * ]);
     * ?>
     * ```
     *
     * Additionally, checkbox values can be checked with a boolean.
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('#form-id', [
     *      'checkbox1' => true,        // fails if checked
     *      'checkbox2' => false,       // fails if unchecked
     * ]);
     * ?>
     * ```
     * 
     * @param $formSelector
     * @param $params
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
     */
    public function cantSeeInFormFields($formSelector, $params) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInFormFields', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if the array of form parameters (name => value) are not set on the form matched with
     * the passed selector.
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('form[name=myform]', [
     *      'input1' => 'non-existent value',
     *      'input2' => 'other non-existent value',
     * ]);
     * ?>
     * ```
     * 
     * To check that an element hasn't been assigned any one of many values, an array can be passed
     * as the value:
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('.form-class', [
     *      'fieldName' => [
     *          'This value shouldn\'t be set',
     *          'And this value shouldn\'t be set',
     *      ],
     * ]);
     * ?>
     * ```
     *
     * Additionally, checkbox values can be checked with a boolean.
     * 
     * ``` php
     * <?php
     * $I->dontSeeInFormFields('#form-id', [
     *      'checkbox1' => true,        // fails if checked
     *      'checkbox2' => false,       // fails if unchecked
     * ]);
     * ?>
     * ```
     * 
     * @param $formSelector
     * @param $params
     * @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
     */
    public function dontSeeInFormFields($formSelector, $params) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInFormFields', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Submits the given form on the page, optionally with the given form values.
     * Give the form fields values as an array.
     *
     * Skipped fields will be filled by their values from the page.
     * You don't need to click the 'Submit' button afterwards.
     * This command itself triggers the request to form's action.
     *
     * You can optionally specify what button's value to include
     * in the request with the last parameter as an alternative to
     * explicitly setting its value in the second parameter, as
     * button values are not otherwise included in the request.
     * 
     * Examples:
     *
     * ``` php
     * <?php
     * $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'));
     * // or
     * $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'), 'submitButtonName');
     *
     * ```
     *
     * For example, given this sample "Sign Up" form:
     *
     * ``` html
     * <form action="/sign_up">
     *     Login: <input type="text" name="user[login]" /><br/>
     *     Password: <input type="password" name="user[password]" /><br/>
     *     Do you agree to out terms? <input type="checkbox" name="user[agree]" /><br/>
     *     Select pricing plan <select name="plan"><option value="1">Free</option><option value="2" selected="selected">Paid</option></select>
     *     <input type="submit" name="submitButton" value="Submit" />
     * </form>
     * ```
     *
     * You could write the following to submit it:
     *
     * ``` php
     * <?php
     * $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)), 'submitButton');
     *
     * ```
     * Note that "2" will be the submitted value for the "plan" field, as it is the selected option.
     * 
     * You can also emulate a JavaScript submission by not specifying any buttons in the third parameter to submitForm.
     * 
     * ```php
     * <?php
     * $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)));
     * 
     * ```
     * 
     * Pair this with seeInFormFields for quick testing magic.
     * 
     * ``` php
     * <?php
     * $form = [
     *      'field1' => 'value',
     *      'field2' => 'another value',
     *      'checkbox1' => true,
     *      // ...
     * ];
     * $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
     * // $I->amOnPage('/path/to/form-page') may be needed
     * $I->seeInFormFields('//form[@id=my-form]', $form);
     * ?>
     * ```
     *
     * Parameter values can be set to arrays for multiple input fields
     * of the same name, or multi-select combo boxes.  For checkboxes,
     * either the string value can be used, or boolean values which will
     * be replaced by the checkbox's value in the DOM.
     *
     * ``` php
     * <?php
     * $I->submitForm('#my-form', [
     *      'field1' => 'value',
     *      'checkbox' => [
     *          'value of first checkbox',
     *          'value of second checkbox,
     *      ],
     *      'otherCheckboxes' => [
     *          true,
     *          false,
     *          false
     *      ],
     *      'multiselect' => [
     *          'first option value',
     *          'second option value'
     *      ]
     * ]);
     * ?>
     * ```
     *
     * Mixing string and boolean values for a checkbox's value is not
     * supported and may produce unexpected results.
     * 
     * @param $selector
     * @param $params
     * @param $button
     * @see \Codeception\Lib\InnerBrowser::submitForm()
     */
    public function submitForm($selector, $params, $button = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('submitForm', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Fills a text field or textarea with the given string.
     *
     * ``` php
     * <?php
     * $I->fillField("//input[@type='text']", "Hello World!");
     * $I->fillField(['name' => 'email'], 'jon@mail.com');
     * ?>
     * ```
     *
     * @param $field
     * @param $value
     * @see \Codeception\Lib\InnerBrowser::fillField()
     */
    public function fillField($field, $value) {
        return $this->scenario->runStep(new \Codeception\Step\Action('fillField', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Selects an option in a select tag or in radio button group.
     *
     * ``` php
     * <?php
     * $I->selectOption('form select[name=account]', 'Premium');
     * $I->selectOption('form input[name=payment]', 'Monthly');
     * $I->selectOption('//form/select[@name=account]', 'Monthly');
     * ?>
     * ```
     *
     * Provide an array for the second argument to select multiple options:
     *
     * ``` php
     * <?php
     * $I->selectOption('Which OS do you use?', array('Windows','Linux'));
     * ?>
     * ```
     *
     * @param $select
     * @param $option
     * @see \Codeception\Lib\InnerBrowser::selectOption()
     */
    public function selectOption($select, $option) {
        return $this->scenario->runStep(new \Codeception\Step\Action('selectOption', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
     *
     * ``` php
     * <?php
     * $I->checkOption('#agree');
     * ?>
     * ```
     *
     * @param $option
     * @see \Codeception\Lib\InnerBrowser::checkOption()
     */
    public function checkOption($option) {
        return $this->scenario->runStep(new \Codeception\Step\Action('checkOption', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Unticks a checkbox.
     *
     * ``` php
     * <?php
     * $I->uncheckOption('#notify');
     * ?>
     * ```
     *
     * @param $option
     * @see \Codeception\Lib\InnerBrowser::uncheckOption()
     */
    public function uncheckOption($option) {
        return $this->scenario->runStep(new \Codeception\Step\Action('uncheckOption', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Attaches a file relative to the Codeception data directory to the given file upload field.
     *
     * ``` php
     * <?php
     * // file is stored in 'tests/_data/prices.xls'
     * $I->attachFile('input[@type="file"]', 'prices.xls');
     * ?>
     * ```
     *
     * @param $field
     * @param $filename
     * @see \Codeception\Lib\InnerBrowser::attachFile()
     */
    public function attachFile($field, $filename) {
        return $this->scenario->runStep(new \Codeception\Step\Action('attachFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * If your page triggers an ajax request, you can perform it manually.
     * This action sends a GET ajax request with specified params.
     *
     * See ->sendAjaxPostRequest for examples.
     *
     * @param $uri
     * @param $params
     * @see \Codeception\Lib\InnerBrowser::sendAjaxGetRequest()
     */
    public function sendAjaxGetRequest($uri, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxGetRequest', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * If your page triggers an ajax request, you can perform it manually.
     * This action sends a POST ajax request with specified params.
     * Additional params can be passed as array.
     *
     * Example:
     *
     * Imagine that by clicking checkbox you trigger ajax request which updates user settings.
     * We emulate that click by running this ajax request manually.
     *
     * ``` php
     * <?php
     * $I->sendAjaxPostRequest('/updateSettings', array('notifications' => true)); // POST
     * $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GET
     *
     * ```
     *
     * @param $uri
     * @param $params
     * @see \Codeception\Lib\InnerBrowser::sendAjaxPostRequest()
     */
    public function sendAjaxPostRequest($uri, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxPostRequest', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * If your page triggers an ajax request, you can perform it manually.
     * This action sends an ajax request with specified method and params.
     *
     * Example:
     *
     * You need to perform an ajax request specifying the HTTP method.
     *
     * ``` php
     * <?php
     * $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
     *
     * ```
     *
     * @param $method
     * @param $uri
     * @param $params
     * @see \Codeception\Lib\InnerBrowser::sendAjaxRequest()
     */
    public function sendAjaxRequest($method, $uri, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxRequest', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Finds and returns the text contents of the given element.
     * If a fuzzy locator is used, the element is found using CSS, XPath, and by matching the full page source by regular expression.
     *
     * ``` php
     * <?php
     * $heading = $I->grabTextFrom('h1');
     * $heading = $I->grabTextFrom('descendant-or-self::h1');
     * $value = $I->grabTextFrom('~<input value=(.*?)]~sgi'); // match with a regex
     * ?>
     * ```
     *
     * @param $cssOrXPathOrRegex
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::grabTextFrom()
     */
    public function grabTextFrom($cssOrXPathOrRegex) {
        return $this->scenario->runStep(new \Codeception\Step\Action('grabTextFrom', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Grabs the value of the given attribute value from the given element.
     * Fails if element is not found.
     *
     * ``` php
     * <?php
     * $I->grabAttributeFrom('#tooltip', 'title');
     * ?>
     * ```
     *
     *
     * @param $cssOrXpath
     * @param $attribute
     * @internal param $element
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::grabAttributeFrom()
     */
    public function grabAttributeFrom($cssOrXpath, $attribute) {
        return $this->scenario->runStep(new \Codeception\Step\Action('grabAttributeFrom', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * @param $field
     *
     * @return array|mixed|null|string
     * @see \Codeception\Lib\InnerBrowser::grabValueFrom()
     */
    public function grabValueFrom($field) {
        return $this->scenario->runStep(new \Codeception\Step\Action('grabValueFrom', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Sets a cookie with the given name and value.
     * You can set additional cookie params like `domain`, `path`, `expire`, `secure` in array passed as last argument.
     *
     * ``` php
     * <?php
     * $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
     * ?>
     * ```
     *
     * @param $name
     * @param $val
     * @param array $params
     * @internal param $cookie
     * @internal param $value
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::setCookie()
     */
    public function setCookie($name, $val, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('setCookie', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Grabs a cookie value.
     * You can set additional cookie params like `domain`, `path` in array passed as last argument.
     *
     * @param $cookie
     *
     * @param array $params
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::grabCookie()
     */
    public function grabCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('grabCookie', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that a cookie with the given name is set.
     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
     *
     * ``` php
     * <?php
     * $I->seeCookie('PHPSESSID');
     * ?>
     * ```
     *
     * @param $cookie
     * @param array $params
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeCookie()
     */
    public function canSeeCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that a cookie with the given name is set.
     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
     *
     * ``` php
     * <?php
     * $I->seeCookie('PHPSESSID');
     * ?>
     * ```
     *
     * @param $cookie
     * @param array $params
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::seeCookie()
     */
    public function seeCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there isn't a cookie with the given name.
     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
     *
     * @param $cookie
     *
     * @param array $params
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
     */
    public function cantSeeCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there isn't a cookie with the given name.
     * You can set additional cookie params like `domain`, `path` as array passed in last argument.
     *
     * @param $cookie
     *
     * @param array $params
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
     */
    public function dontSeeCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCookie', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Unsets cookie with the given name.
     * You can set additional cookie params like `domain`, `path` in array passed as last argument.
     *
     * @param $cookie
     *
     * @param array $params
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::resetCookie()
     */
    public function resetCookie($name, $params = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('resetCookie', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given element exists on the page and is visible.
     * You can also specify expected attributes of this element.
     *
     * ``` php
     * <?php
     * $I->seeElement('.error');
     * $I->seeElement('//form/input[1]');
     * $I->seeElement('input', ['name' => 'login']);
     * $I->seeElement('input', ['value' => '123456']);
     *
     * // strict locator in first arg, attributes in second
     * $I->seeElement(['css' => 'form input'], ['name' => 'login']);
     * ?>
     * ```
     *
     * @param $selector
     * @param array $attributes
     * @return
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeElement()
     */
    public function canSeeElement($selector, $attributes = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeElement', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given element exists on the page and is visible.
     * You can also specify expected attributes of this element.
     *
     * ``` php
     * <?php
     * $I->seeElement('.error');
     * $I->seeElement('//form/input[1]');
     * $I->seeElement('input', ['name' => 'login']);
     * $I->seeElement('input', ['value' => '123456']);
     *
     * // strict locator in first arg, attributes in second
     * $I->seeElement(['css' => 'form input'], ['name' => 'login']);
     * ?>
     * ```
     *
     * @param $selector
     * @param array $attributes
     * @return
     * @see \Codeception\Lib\InnerBrowser::seeElement()
     */
    public function seeElement($selector, $attributes = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeElement', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given element is invisible or not present on the page.
     * You can also specify expected attributes of this element.
     *
     * ``` php
     * <?php
     * $I->dontSeeElement('.error');
     * $I->dontSeeElement('//form/input[1]');
     * $I->dontSeeElement('input', ['name' => 'login']);
     * $I->dontSeeElement('input', ['value' => '123456']);
     * ?>
     * ```
     *
     * @param $selector
     * @param array $attributes
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeElement()
     */
    public function cantSeeElement($selector, $attributes = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeElement', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given element is invisible or not present on the page.
     * You can also specify expected attributes of this element.
     *
     * ``` php
     * <?php
     * $I->dontSeeElement('.error');
     * $I->dontSeeElement('//form/input[1]');
     * $I->dontSeeElement('input', ['name' => 'login']);
     * $I->dontSeeElement('input', ['value' => '123456']);
     * ?>
     * ```
     *
     * @param $selector
     * @param array $attributes
     * @see \Codeception\Lib\InnerBrowser::dontSeeElement()
     */
    public function dontSeeElement($selector, $attributes = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeElement', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there are a certain number of elements matched by the given locator on the page.
     * 
     * ``` php
     * <?php
     * $I->seeNumberOfElements('tr', 10);
     * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
     * ?>
     * ```
     * @param $selector
     * @param mixed $expected:
     * - string: strict number
     * - array: range of numbers [0,10]
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
     */
    public function canSeeNumberOfElements($selector, $expected) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElements', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that there are a certain number of elements matched by the given locator on the page.
     * 
     * ``` php
     * <?php
     * $I->seeNumberOfElements('tr', 10);
     * $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
     * ?>
     * ```
     * @param $selector
     * @param mixed $expected:
     * - string: strict number
     * - array: range of numbers [0,10]
     * @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
     */
    public function seeNumberOfElements($selector, $expected) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeNumberOfElements', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given option is selected.
     *
     * ``` php
     * <?php
     * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
     * ?>
     * ```
     *
     * @param $selector
     * @param $optionText
     *
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
     */
    public function canSeeOptionIsSelected($select, $optionText) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeOptionIsSelected', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given option is selected.
     *
     * ``` php
     * <?php
     * $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
     * ?>
     * ```
     *
     * @param $selector
     * @param $optionText
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
     */
    public function seeOptionIsSelected($select, $optionText) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeOptionIsSelected', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given option is not selected.
     *
     * ``` php
     * <?php
     * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
     * ?>
     * ```
     *
     * @param $selector
     * @param $optionText
     *
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
     */
    public function cantSeeOptionIsSelected($select, $optionText) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeOptionIsSelected', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the given option is not selected.
     *
     * ``` php
     * <?php
     * $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
     * ?>
     * ```
     *
     * @param $selector
     * @param $optionText
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
     */
    public function dontSeeOptionIsSelected($select, $optionText) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeOptionIsSelected', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Asserts that current page has 404 response status code.
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seePageNotFound()
     */
    public function canSeePageNotFound() {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seePageNotFound', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Asserts that current page has 404 response status code.
     * @see \Codeception\Lib\InnerBrowser::seePageNotFound()
     */
    public function seePageNotFound() {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seePageNotFound', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that response code is equal to value provided.
     *
     * @param $code
     *
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
     */
    public function canSeeResponseCodeIs($code) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that response code is equal to value provided.
     *
     * @param $code
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
     */
    public function seeResponseCodeIs($code) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page title contains the given string.
     *
     * ``` php
     * <?php
     * $I->seeInTitle('Blog - Post #1');
     * ?>
     * ```
     *
     * @param $title
     *
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::seeInTitle()
     */
    public function canSeeInTitle($title) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInTitle', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page title contains the given string.
     *
     * ``` php
     * <?php
     * $I->seeInTitle('Blog - Post #1');
     * ?>
     * ```
     *
     * @param $title
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::seeInTitle()
     */
    public function seeInTitle($title) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInTitle', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page title does not contain the given string.
     *
     * @param $title
     *
     * @return mixed
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
     */
    public function cantSeeInTitle($title) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInTitle', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that the page title does not contain the given string.
     *
     * @param $title
     *
     * @return mixed
     * @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
     */
    public function dontSeeInTitle($title) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInTitle', func_get_args()));
    }
}
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('login to wp-admin');
$I->amOnPage( site_url().'/wp-login.php' );
$I->fillField('Username', 'admin');
$I->fillField('Password','admin');
$I->click('Log In');
$I->see('Dashboard');
<?php 

/**
*  This test is desnged to test the impressions/conversions systems of landing pages.
*  Systems tested:
*   -  Dmummy landing page creation
*   -  Impression/Conversion UI display on landing page edit screen
*   -  Cear individual landing page stats buttons.
*   -  Manually setting impressions/conversions
*   -  Makes sure landing page does not 404
*   -  Frontend impression ajax systems
*   -  Variation rotation systems
*   -  Conversion tracking system for inbount form
*   -  Conversion tracking system for tracked link
*/

/* create test landing page */
$lp_id = inbound_install_example_lander();
shell_exec('here');
shell_exec($lp_id);
$permalink = get_post_permalink( $lp_id , false ); 
shell_exec($permalink);
$I = new AcceptanceTester($scenario);


$I->wantTo('check example landing page is editable');
$I->amOnPage( admin_url( 'post.php?post='. $lp_id .'&action=edit&frontend=false') );
$I->seeInField( '#title','A/B Testing Landing Page Example');

$I->wantTo('check if impressions are correct for variation a');
$imp = $I->grabTextFrom('#lp-variation-A .bab-stat-span-impressions');
$I->assertContains( '30' , $imp );

$I->wantTo('check check impressions for variation b');
$imp = $I->grabTextFrom('#lp-variation-B .bab-stat-span-impressions');
$I->assertContains( '35' , $imp , ''  );

$I->wantTo('check conversions for variation a');
$con = $I->grabTextFrom('#lp-variation-A .bab-stat-span-conversions');
$I->assertContains( '10' , $con , '' );

$I->wantTo('check conversions for variation b');
$con = $I->grabTextFrom('#lp-variation-B .bab-stat-span-conversions');
$I->assertContains( '15' , $con  );

$I->wantTo('check the conversion rate of variation a');
$per = $I->grabTextFrom('#lp-variation-A .bab-stat-span-conversion_rate');
$I->assertContains( '33' , $per  );

$I->wantTo('check the conversion rate of variation b');
$per = $I->grabTextFrom('#lp-variation-B .bab-stat-span-conversion_rate');
$I->assertContains( '43' , $per  );



<?php 

$I = new AcceptanceTester($scenario);
$I->wantTo('Make sure the default WordPress homepage loads.');
$I->amOnPage( site_url() );
$I->see('Hello world!');

<?php
// Here you can initialize variables that will be available to your tests
# Codeception Test Suite Configuration

# suite for functional (integration) tests.
# emulate web requests and make application process them.
# Include one of framework modules (Symfony2, Yii2, Laravel4) to use it.

class_name: FunctionalTester
modules:
    enabled: [Filesystem, FunctionalHelper]
<?php //[STAMP] fa259e6277a310881c0cdeb89563ce4c

// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile


use Codeception\Module\Filesystem;
use Codeception\Module\FunctionalHelper;

/**
 * Inherited Methods
 * @method void wantToTest($text)
 * @method void wantTo($text)
 * @method void execute($callable)
 * @method void expectTo($prediction)
 * @method void expect($prediction)
 * @method void amGoingTo($argumentation)
 * @method void am($role)
 * @method void lookForwardTo($achieveValue)
 * @method void comment($description)
 * @method void haveFriend($name, $actorClass = null)
 *
 * @SuppressWarnings(PHPMD)
*/
class FunctionalTester extends \Codeception\Actor
{
   
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Enters a directory In local filesystem.
     * Project root directory is used by default
     *
     * @param $path
     * @see \Codeception\Module\Filesystem::amInPath()
     */
    public function amInPath($path) {
        return $this->scenario->runStep(new \Codeception\Step\Condition('amInPath', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Opens a file and stores it's content.
     *
     * Usage:
     *
     * ``` php
     * <?php
     * $I->openFile('composer.json');
     * $I->seeInThisFile('codeception/codeception');
     * ?>
     * ```
     *
     * @param $filename
     * @see \Codeception\Module\Filesystem::openFile()
     */
    public function openFile($filename) {
        return $this->scenario->runStep(new \Codeception\Step\Action('openFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Deletes a file
     *
     * ``` php
     * <?php
     * $I->deleteFile('composer.lock');
     * ?>
     * ```
     *
     * @param $filename
     * @see \Codeception\Module\Filesystem::deleteFile()
     */
    public function deleteFile($filename) {
        return $this->scenario->runStep(new \Codeception\Step\Action('deleteFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Deletes directory with all subdirectories
     *
     * ``` php
     * <?php
     * $I->deleteDir('vendor');
     * ?>
     * ```
     *
     * @param $dirname
     * @see \Codeception\Module\Filesystem::deleteDir()
     */
    public function deleteDir($dirname) {
        return $this->scenario->runStep(new \Codeception\Step\Action('deleteDir', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Copies directory with all contents
     *
     * ``` php
     * <?php
     * $I->copyDir('vendor','old_vendor');
     * ?>
     * ```
     *
     * @param $src
     * @param $dst
     * @see \Codeception\Module\Filesystem::copyDir()
     */
    public function copyDir($src, $dst) {
        return $this->scenario->runStep(new \Codeception\Step\Action('copyDir', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks If opened file has `text` in it.
     *
     * Usage:
     *
     * ``` php
     * <?php
     * $I->openFile('composer.json');
     * $I->seeInThisFile('codeception/codeception');
     * ?>
     * ```
     *
     * @param $text
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Module\Filesystem::seeInThisFile()
     */
    public function canSeeInThisFile($text) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInThisFile', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks If opened file has `text` in it.
     *
     * Usage:
     *
     * ``` php
     * <?php
     * $I->openFile('composer.json');
     * $I->seeInThisFile('codeception/codeception');
     * ?>
     * ```
     *
     * @param $text
     * @see \Codeception\Module\Filesystem::seeInThisFile()
     */
    public function seeInThisFile($text) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInThisFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks the strict matching of file contents.
     * Unlike `seeInThisFile` will fail if file has something more than expected lines.
     * Better to use with HEREDOC strings.
     * Matching is done after removing "\r" chars from file content.
     *
     * ``` php
     * <?php
     * $I->openFile('process.pid');
     * $I->seeFileContentsEqual('3192');
     * ?>
     * ```
     *
     * @param $text
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Module\Filesystem::seeFileContentsEqual()
     */
    public function canSeeFileContentsEqual($text) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileContentsEqual', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks the strict matching of file contents.
     * Unlike `seeInThisFile` will fail if file has something more than expected lines.
     * Better to use with HEREDOC strings.
     * Matching is done after removing "\r" chars from file content.
     *
     * ``` php
     * <?php
     * $I->openFile('process.pid');
     * $I->seeFileContentsEqual('3192');
     * ?>
     * ```
     *
     * @param $text
     * @see \Codeception\Module\Filesystem::seeFileContentsEqual()
     */
    public function seeFileContentsEqual($text) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileContentsEqual', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks If opened file doesn't contain `text` in it
     *
     * ``` php
     * <?php
     * $I->openFile('composer.json');
     * $I->dontSeeInThisFile('codeception/codeception');
     * ?>
     * ```
     *
     * @param $text
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Module\Filesystem::dontSeeInThisFile()
     */
    public function cantSeeInThisFile($text) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInThisFile', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks If opened file doesn't contain `text` in it
     *
     * ``` php
     * <?php
     * $I->openFile('composer.json');
     * $I->dontSeeInThisFile('codeception/codeception');
     * ?>
     * ```
     *
     * @param $text
     * @see \Codeception\Module\Filesystem::dontSeeInThisFile()
     */
    public function dontSeeInThisFile($text) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInThisFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Deletes a file
     * @see \Codeception\Module\Filesystem::deleteThisFile()
     */
    public function deleteThisFile() {
        return $this->scenario->runStep(new \Codeception\Step\Action('deleteThisFile', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if file exists in path.
     * Opens a file when it's exists
     *
     * ``` php
     * <?php
     * $I->seeFileFound('UserModel.php','app/models');
     * ?>
     * ```
     *
     * @param $filename
     * @param string $path
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Module\Filesystem::seeFileFound()
     */
    public function canSeeFileFound($filename, $path = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileFound', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if file exists in path.
     * Opens a file when it's exists
     *
     * ``` php
     * <?php
     * $I->seeFileFound('UserModel.php','app/models');
     * ?>
     * ```
     *
     * @param $filename
     * @param string $path
     * @see \Codeception\Module\Filesystem::seeFileFound()
     */
    public function seeFileFound($filename, $path = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileFound', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if file does not exists in path
     *
     * @param $filename
     * @param string $path
     * Conditional Assertion: Test won't be stopped on fail
     * @see \Codeception\Module\Filesystem::dontSeeFileFound()
     */
    public function cantSeeFileFound($filename, $path = null) {
        return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeFileFound', func_get_args()));
    }
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks if file does not exists in path
     *
     * @param $filename
     * @param string $path
     * @see \Codeception\Module\Filesystem::dontSeeFileFound()
     */
    public function dontSeeFileFound($filename, $path = null) {
        return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeFileFound', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Erases directory contents
     *
     * ``` php
     * <?php
     * $I->cleanDir('logs');
     * ?>
     * ```
     *
     * @param $dirname
     * @see \Codeception\Module\Filesystem::cleanDir()
     */
    public function cleanDir($dirname) {
        return $this->scenario->runStep(new \Codeception\Step\Action('cleanDir', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Saves contents to file
     *
     * @param $filename
     * @param $contents
     * @see \Codeception\Module\Filesystem::writeToFile()
     */
    public function writeToFile($filename, $contents) {
        return $this->scenario->runStep(new \Codeception\Step\Action('writeToFile', func_get_args()));
    }
}
<?php
// Here you can initialize variables that will be available to your tests
# Codeception Test Suite Configuration

# suite for unit (internal) tests.
class_name: UnitTester
modules:
    enabled: [Asserts, UnitHelper]
<?php //[STAMP] c8568e8eab4a240544c36ae031f88bd8

// This class was automatically generated by build task
// You should not change it manually as it will be overwritten on next build
// @codingStandardsIgnoreFile


use Codeception\Module\Asserts;
use Codeception\Module\UnitHelper;

/**
 * Inherited Methods
 * @method void wantToTest($text)
 * @method void wantTo($text)
 * @method void execute($callable)
 * @method void expectTo($prediction)
 * @method void expect($prediction)
 * @method void amGoingTo($argumentation)
 * @method void am($role)
 * @method void lookForwardTo($achieveValue)
 * @method void comment($description)
 * @method void haveFriend($name, $actorClass = null)
 *
 * @SuppressWarnings(PHPMD)
*/
class UnitTester extends \Codeception\Actor
{
   
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that two variables are equal.
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     *
     * @return mixed
     * @see \Codeception\Module\Asserts::assertEquals()
     */
    public function assertEquals($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertEquals', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that two variables are not equal
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNotEquals()
     */
    public function assertNotEquals($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that two variables are same
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     *
     * @return mixed
     * @see \Codeception\Module\Asserts::assertSame()
     */
    public function assertSame($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertSame', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that two variables are not same
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNotSame()
     */
    public function assertNotSame($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that expected is greater than actual
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertGreaterThan()
     */
    public function assertGreaterThan($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * @deprecated
     * @see \Codeception\Module\Asserts::assertGreaterThen()
     */
    public function assertGreaterThen($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that expected is greater or equal than actual
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertGreaterThanOrEqual()
     */
    public function assertGreaterThanOrEqual($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * @deprecated
     * @see \Codeception\Module\Asserts::assertGreaterThenOrEqual()
     */
    public function assertGreaterThenOrEqual($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that expected is less than actual
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertLessThan()
     */
    public function assertLessThan($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that expected is less or equal than actual
     *
     * @param        $expected
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertLessThanOrEqual()
     */
    public function assertLessThanOrEqual($expected, $actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that haystack contains needle
     *
     * @param        $needle
     * @param        $haystack
     * @param string $message
     * @see \Codeception\Module\Asserts::assertContains()
     */
    public function assertContains($needle, $haystack, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertContains', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that haystack doesn't contain needle.
     *
     * @param        $needle
     * @param        $haystack
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNotContains()
     */
    public function assertNotContains($needle, $haystack, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that variable is empty.
     *
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertEmpty()
     */
    public function assertEmpty($actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that variable is not empty.
     *
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNotEmpty()
     */
    public function assertNotEmpty($actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that variable is NULL
     *
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNull()
     */
    public function assertNull($actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNull', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that variable is not NULL
     *
     * @param        $actual
     * @param string $message
     * @see \Codeception\Module\Asserts::assertNotNull()
     */
    public function assertNotNull($actual, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that condition is positive.
     *
     * @param        $condition
     * @param string $message
     * @see \Codeception\Module\Asserts::assertTrue()
     */
    public function assertTrue($condition, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertTrue', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Checks that condition is negative.
     *
     * @param        $condition
     * @param string $message
     * @see \Codeception\Module\Asserts::assertFalse()
     */
    public function assertFalse($condition, $message = null) {
        return $this->scenario->runStep(new \Codeception\Step\Action('assertFalse', func_get_args()));
    }

 
    /**
     * [!] Method is generated. Documentation taken from corresponding module.
     *
     * Fails the test with message.
     *
     * @param $message
     * @see \Codeception\Module\Asserts::fail()
     */
    public function fail($message) {
        return $this->scenario->runStep(new \Codeception\Step\Action('fail', func_get_args()));
    }
}
<?php
// Here you can initialize variables that will be available to your tests
/**
 *  PhantomJs server for calling webpages & processing JS
 *  returns page content
 */

var args = require('system').args;
var address = args[1];
var page = new WebPage();

var renderPage = function(){

    page = require('webpage').create();
    var myArgs = Array.prototype.slice.call(arguments),
        url_str = myArgs[0];

	 console.log('accessing:'+url_str);
	
	page.onError = function(msg){console.log('js error');}
	
    /**
     * From PhantomJS documentation:
     * This callback is invoked when there is a JavaScript console. The callback may accept up to three arguments:
     * the string for the message, the line number, and the source identifier.
     */
    page.onConsoleMessage = function (msg, line, source) {
        console.log('console> ' + msg);
    };

    /**
     * From PhantomJS documentation:
     * This callback is invoked when there is a JavaScript alert. The only argument passed to the callback is the string for the message.
     */
    page.onAlert = function (msg) {
        console.log('alert!!> ' + msg);
    };

    /**
     * Handle Redirection
     */
    page.onNavigationRequested = function(url_sub_str, type, willNavigate, main) {
        if (main && url_sub_str != url_str) {
            url_str = url_sub_str;
            console.log("redirect caught");
            page.close();
            setTimeout(function() {
				renderPage(url_str)
			},1);
        }
    };
	
	page.onResourceReceived = function (response) {
		//console.log('Receive ' + JSON.stringify(response, undefined, 4));
	};
	
	//page.onLoadFinished = function() { console.log(&quot;onLoadFinished FIRED&quot;); }

    /**
     * Open the web page and run RRunner
     */
    page.open(url_str, function(status) {
		console.log('here');
        if (status === 'success') {
            console.log(page.content); 
			page.close();
			setTimeout( function() {
				
				phantom.exit();
			} , 5000);
        } else {
            console.log('failed');			
            phantom.exit();
        }
    });
};


address = 'http://local.wordpress.dev/test.php';
//address = 'http://local.wordpress.dev/';
//address = 'http://www.simpleweb.org/';
renderPage(address);


<?php
//echo shell_exec( '/usr/bin/phantomjs /vagrant/www/wordpress-default/wp-content/plugins/landing-pages/tests/phantomjs/server.js' );
//sleep(10);

//$output = shell_exec('/usr/bin/phantomjs server.js');
//echo "<pre>$output</pre>";
error_reporting(E_ALL);
session_write_close();
$result = shell_exec('phantomjs  --web-security=false --ssl-protocol=any server.js ' . $_GET['url'] ); 
echo $result;
#!/bin/sh
export DISPLAY=:0
phantomjs --ignore-ssl-errors=true server.js  2>&1
<?php
/**
 * Bootstrap the plugin unit testing environment.
 *
 * @package wordpress-plugin-tests
 */

/* load wp environemnt */
require '../../../wp-load.php';

/* load plugins */
require '../../../wp-admin/includes/plugin.php';

/**
*  Replacement for wp_remote_get
*  processes javascript through PhantomJs
*/
function inbound_remote_get( $url ) {
	$response = wp_remote_get( 
		add_query_arg( 
			array( 'url' => urlencode( $url ) ) , 
			LANDINGPAGES_URLPATH . 'tests/phantomjs/server.php'
		) 
	);
	
	return $response;	
} 



<?php

/**
 * Tests to test that that testing framework is testing tests. Meta, huh?
 *
 * @package wordpress-plugins-tests
 */
class Tests_Activation extends PHPUnit_Framework_TestCase {

	/**
	* Run a simple test to ensure that the tests are running
	*/
	function test_tests() {
		$this->assertTrue( true );
	}

	/**
	* Ensure landing pages is active
	*/
	function test_lading_pages_activated() {
		$this->assertTrue( is_plugin_active( 'landing-pages/landing-pages.php' ) );
	}

	/**
	* Ensure that the Leads has been installed and activated.
	*/
	function test_leads_activated() {
		$this->assertTrue( is_plugin_active( 'leads/leads.php' ) );
	}

	/**
	* Ensure that the Calls to Action has been installed and activated.
	*/
	function test_cta_activated() {
		$this->assertTrue( is_plugin_active( 'cta/calls-to-action.php' ) );
	}

	/**
	* Run upgrade routines and check option to see if complete
	*/
	function test_run_upgrade_routines() {
		include_once LANDINGPAGES_PATH . 'classes/class.activation.php';
		include_once LANDINGPAGES_PATH . 'classes/class.activation.upgrade-routines.php';
		Landing_Pages_Activation::run_updates();
		$this->assertTrue( true );
	}

}

?>
<?php

/**
 * Test design to juse phantomjs to interact with front end. This test is disabled in favor for codeception tests
 *
 * @package wordpress-plugins-tests
 */
class Tests_Statistics extends PHPUnit_Framework_TestCase {

    var $lp_id;
    var $variations;

    /**
     * setup
     */
    function setUp() {
		return;
        /* includes */
        include_once LANDINGPAGES_PATH . 'modules/module.install.php';
        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';

        $this->lp_id = inbound_install_example_lander();
        /*  clear the stats */
        $this->variations = Landing_Pages_Statistics::get_variations($this->lp_id );
        foreach ($this->variations as $vid) {
            Landing_Pages_Statistics::set_impression_count( $this->lp_id , $vid, 0 );
            Landing_Pages_Statistics::set_conversion_count( $this->lp_id , $vid, 0 );
        }		
    }

	/**
	*  Tear down
	*/
	function tearDown() {	
		return;
		//delete_option('lp_settings_general');
		//wp_delete_post( $this->lp_id , false );
	}
	
	
    /**
     * Test is Landing_Pages_Statistics::read_statistics works
     */
    function test_read_statistics() {
		return;
		
        /* includes */
        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';

        $stats = Landing_Pages_Statistics::read_statistics( $this->lp_id );

        $this->assertEquals( count($stats) , 3 );
        $this->assertEquals( $stats['impressions'][0] , 0 );
        $this->assertEquals( $stats['conversions'][0] , 0 );
        $this->assertEquals( $stats['impressions'][1] , 0 );
        $this->assertEquals( $stats['conversions'][1] , 0 );
    }

    /**
     * launch a landing page
     */
    function test_landing_page_read() {
		return;
		
        /* includes */
        include_once LANDINGPAGES_PATH . 'classes/class.statistics.php';

        $permalink = get_post_permalink( $this->lp_id , false ); 
		echo $permalink."\r\n";	
		$permalink = 'http://local.wordpress.dev/go/ab-testing-landing-page-example-104/?lp-variation-id=1';
		$permalink = 'http://local.wordpress.dev/';
        print_r(inbound_remote_get( $permalink ));   
		/*
		sleep(5);
        $response = inbound_remote_get( $permalink );
		sleep(5);
        $response = inbound_remote_get( $permalink );
		sleep(5);
        $response = inbound_remote_get( $permalink );
		sleep(5);
        $response = inbound_remote_get( add_query_arg( array('lp-variation-id'=> 0  ) , $permalink ) );
		sleep(5);
        $response = inbound_remote_get( add_query_arg( array('lp-variation-id'=> 1  ) , $permalink ) );
		sleep(5);
		*/
        $stats = Landing_Pages_Statistics::read_statistics( $this->lp_id );
        print_r($stats);
		
        $this->assertEquals( $stats['impressions'][0] , 3 );
        $this->assertEquals( $stats['conversions'][0] , 0 );
        $this->assertEquals( $stats['impressions'][1] , 3 );
        $this->assertEquals( $stats['conversions'][1] , 0 );
    }
}