Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
114 kB
3
Indexable
Never
/* eslint-disable no-prototype-builtins */
/*eslint-env es6*/
/*eslint-env browser*/
/*global qaTestMode:true*/
/*global Insider*/

//********************************************************************************************** */
//---------------------------------------- README ------------------------------------------------/
//********************************************************************************************** */
/**
 * Copyright (c) 2019
 *
 * @summary Browser based, QA Test logger.
 * @author Batuhan KOZAN <kozanb@gmail.com>
 * @author Doruk YURTSEVER <drkydk@gmail.com>
 * @author Muhammed İKİNCİ <muhammedikinci@outlook.com>
 *
 * Created at     : 2019-01-02 00:00:00
 * 
 * Start Initialize : 
 *      qaTestMode.init() -> hitListener()
 *      hitListener() (payload_data)-> hitParser(payload_data)
 *      hitParser() 
 *          (parsed_payload)
 *              -> checkgetCategories()
 *              -> checkgetCurrentProduct()
 *                  -> checkProductCategories()
 *              -> checkMain()
 *              -> checkCart()
 *              -> checkWishlist()
 *              -> checkRegister()
 *              -> checkAfter()
 *          Always Running
 *              -> checkLangAndCurrency
 *              -> checkTotals
 *              -> checkSearch
 *              -> checkLogin
 *              -> checkCoupon
 *              -> _vairoDumpStorage (storage Listener)
 */
/*
    Kurulum & Kullanımı:

    tamperMonkey eklentisini indirip kurun. Yeni betik oluştur diyerek README'nin hemen altındaki yorum satırlarını
    Tamper Monkey Start ve Tamper Monkey End satırları hariç yapıştırın, kaydedin.
    Sonra tekrar aynı betik(script) içerisine girerek ayarlar'a geçin ve ayarları
    Position: 1
    Run at: document-start
    Run only in top frame: Yes

    Şeklinde ayarlayın, kaydedin.

    Tamper'ın sağ üstteki genel ayarlarında Externals(Dış Betikler) Update Interval(Güncelleme sıklığı)
    Always(Her zaman) OLMALIDIR!

    Lokal dosyayı göstererek web server(XAMPP, apache) kullanmadan çalıştırmanız için chrome uzantı ayarlarından
    tamperMonkey'in detaylarına tıkladığınızda "Allow access to file URLs" açık OLMALIDIR!

    !!!!!! DEĞİŞİKLİK YAPTIĞINIZDA NE KADAR KÜÇÜK OLURSA OLSUN PUSHLAMADAN ÖNCE MUTLAKA ETRAFLICA TEST EDİN     !!!!!!!!
    !!!!!! Fonksiyonları refactor ederken işlev kaybı ve eksik fallback olmamasına dikkat edin                  !!!!!!!!
    !!!!!! Hataya düştüğünde kullanıcının kesinlikle bilmesi gereken durumları try catch'e alın, açıkça loglayın!!!!!!!!
    !!!!!! try-catch'leri çok çok kritik bir hata olmadıkça kesinlikle iç içe yazmayın! Backtrace yapamazsınız  !!!!!!!!
    !!!!!! İşlemler window ve DOM yüklenmeden de yapılabildiği için fonksiyonlar beklenmedik sonuçlar verebilir !!!!!!!!
    !!!!!! spApi, sQuery, Insider fonksiyonlarını kullanmayın. Var olanları pure-javascript'e çevirin           !!!!!!!!
    !!!!!! Global değişkenler window ya da spApi'ye değil, qaTestMode içerisine atanmalı ve oradan okunmalı     !!!!!!!!
    !!!!!! Kullanılan this'lerin hepsi, this -> qaTestMode 'u gösterecek şekilde yazıldı. Her this aynı işi yapmaz !!!!!
    !!!!!! Ana scope'ta olmayan fonksiyonlar içerisine yazılan this'ler yalnızca o lokal fonksiyonu işaret eder !!!!!!!!
*/

//********************************************************************************************** */
//---------------------------------------- README END --------------------------------------------/
//********************************************************************************************** */

/** Tamper Monkey Start */
// ==UserScript==
// @name         QA Test Logger
// @namespace    http://tampermonkey.net/
// @version      1
// @description  Browser based, QA Test logger.
// @author       Doruk Yurtsever
// @author       Muhammed İKİNCİ
// @match        *://*/*
// @require      file://_filepath_/insider/0000_Misc/QATestCodes.js (Lokal dosyayı göstererek çalışın yoksa delay olur)
// @grant        none
// ==/UserScript==
/** Tamper Monkey End */

window.qaTestMode = {
    init: function () {
        this.log('QA Test Mode', 'Initialized');
        // Run Hit listener
        this.hitListener();

        // Run product event listener
        this.productEventListener();

        // Run Storage Listener
        this._vairoDumpStorage(true);

        // Log durumunu bastır
        if (window.localStorage['vTestLogLevel']) {
            window.console.log('%c ########################', 'font-size:20px;color:red');
            window.console.log('%c' +
                window.localStorage['vTestLogLevel'].toUpperCase() + ' LOGLARI DEVRE DIŞI', 'font-size:20px;color:red');
            window.console.log('%c ########################', 'font-size:20px;color:red');
        }

        // TODO
        // Bu kontrol pek sağlıklı değil. Bazı durumlarda fazladan API yüklenirken hata oldu! hatası bastırıyor
        // HitSend'in açık olup olmadığını kontrol edebileceğimiz daha iyi bir mantık bulmamız gerekiyor.
        // Site yüklendikten sonra hitSend kontrol et, ona göre offline mode ya da hitListener çalıştır
        document.addEventListener('DOMContentLoaded', function () {
            window.console.log('%cDocument Load Triggered', 'color:magenta;');

            function getApiUrl() {
                try {
                    return Insider.partner.apiUrl;
                } catch (e) {
                    qaTestMode.errorLog('API yüklenirken hata!', e);

                    return '';
                }
            }

            // TODO -> Bu kontroller daha sağlıklı yazılmalı. hitSend kontrolünü nasıl sağlıklı yapacağımızı bilmiyoruz.
            // API varlığını & hitSend'i kontrol et
            // Panel URL'ini bastır
            // hitSend durumuna göre hitParser'ı ya da qaTestMode.offlineMode 'u çalıştır.
            setTimeout(function () {
                if (!window.panelUrlPrinted) {
                    if (window.Insider) {
                        window.console.log('%cPanel Url: %s', 'font-size:18px;font-weight:bold',
                            ((window.Insider.partner || []).apiUrl || '').replace('api', 'inone'));
                    } else if (getApiUrl()) {
                        console.log('%cPanel Url: %s', 'font-size:18px;font-weight:bold',
                            getApiUrl().replace('api', 'inone'));
                    } else if ((document.querySelectorAll('[src*="/ins.js"]')[0] || []).src) {
                        var _url = ((document.querySelectorAll('[src*="/ins.js"]')[0] || []).src.split('?')[0] || '')
                            .replace('api', 'inone').replace('/ins.js', '');

                        qaTestMode.errorLog('API entegrasyonunda problem var!', 'ins.js Çalışmıyor!');
                        console.log('%cPanel Url(API Çalışmıyor): %s', 'font-size:18px;font-weight:bold',
                            _url);
                    } else {
                        qaTestMode.errorLog('API entegrasyonunda problem var!', 'ins.js Çalışmıyor!');
                        console.log('%cPanel Url Bulunamadı! %s', 'font-size:18px;font-weight:bold',
                            'window.Insider.partner, spApi.apiUrl, ins.js bilgilerini kontrol edin.');
                    }
                }

                if ((window.spApi || []).hitSend === false) {
                    qaTestMode.warnLog('hitSend', spApi.hitSend);
                    qaTestMode.offlineMode();
                }
            }, 5000);

            /** SETTİMEOUT'LU ESKİ VE KULLANIŞSIZ APİ İNİT KONTROLÜNÜN YENİ HALİ SORUN ÇIKARSA ALTERNATİF OLARAK
             * FAYDANALANABİLİRSİNİZ
             */

            // API varlığını & hitSend'i kontrol et
            // Panel URL'ini bastır
            // hitSend durumuna göre hitParser'ı ya da qaTestMode.offlineMode 'u çalıştır.
            // var counter = 3;

            // function checkApiInit() {
            //     setTimeout(function () {
            //         if (window.Insider || window.spApi) {
            //             var insJsSRC = (document.querySelectorAll('[src*="/ins.js"]')[0] || []).src || '';
            //             var hitSend = (httpGet(insJsSRC) || '').indexOf('dataCollectStatus:!0') !== -1;

            //             if (!window.Insider) {
            //                 qaTestMode.errorLog('Yeni api geçişi yapılmamış!',
            //                     'OPAM\'dan taskı yeni api\'ye geçirmesini rica edin!');
            //             }

            //             if (hitSend) {
            //                 if (!window.panelUrlPrinted) {
            //                     if (window.Insider) {
            //                         window.console.log('%cPanel Url: %s', 'font-size:18px;font-weight:bold',
            //                             ((window.Insider.partner || []).apiUrl || '').replace('api', 'inone'));
            //                     } else {
            //                         qaTestMode.errorLog('API entegrasyonunda problem var!', 'ins.js Çalışmıyor!');
            //                         console.log('%cPanel Url Bulunamadı! %s', 'font-size:18px;font-weight:bold',
            //                             'window.Insider.partner, spApi.apiUrl, ins.js bilgilerini kontrol edin.');
            //                     }
            //                 }
            //             } else {
            //                 qaTestMode.warnLog('hitSend', hitSend);
            //                 qaTestMode.offlineMode();
            //             }
            //         } else {

            //             if (counter > 0) {
            //                 qaTestMode.warnLog('API henüz yüklenmedi! Tekrar deneniyor... Son', counter);

            //                 counter--;

            //                 checkApiInit();
            //             } else {
            //                 qaTestMode.errorLog('ins.js entegrasyonunda problem var!',
            //                     'api geldiğinde otomatik çalışacaktır. TEKRAR DENEMEK İÇİN: qaTestMode.tryAgainCheckApiInit()');

            //                 qaTestMode.tryAgainCheckApiInit = function () {
            //                     counter = 3;
            //                     checkApiInit();
            //                 };
            //             }
            //         }
            //     }, 1000);
            // }

            // checkApiInit();
        });

        // Window'a getPayload fonksiyonunu koy
        window._vairoGetPayload = function () {
            return JSON.stringify({
                product: Insider.systemRules.getCurrentProduct()
            });
        };

        // Görüntülenen ürünü payload ile ekleyen fonksiyon
        window._vairoAddCurrent = function () {
            qaTestMode.systemRule.spAddToCart().addToBasket(
                qaTestMode.systemRule.getCurrentProduct().id, null, JSON.parse(window._vairoGetPayload()));
        };

        // Alınan tüm errorleri _vairoErrors altında logla. Logları yazan fonksiyon qaTestMode.errorLog altında
        window._vairoErrors = window.localStorage['vairo-error-logstack'] ?
            JSON.parse(window.localStorage['vairo-error-logstack']) : 'No Error Log';

        window._vairoLogs = window.localStorage['vairo-general-logstack'] ?
            JSON.parse(window.localStorage['vairo-general-logstack']) : 'No Logs to View';

        // Son görüntülenmiş ürünü spAddToCart ile payload kullanarak ekleyen fonksiyon
        window._vairoSpAddLast = function () {
            if (window.localStorage['vairo-last-id'] && window.localStorage['vairo-last-payload']) {
                qaTestMode.systemRule.spAddToCart().addToBasket(window.localStorage['vairo-last-id'], null,
                    qaTestMode.parseJSON(window.localStorage['vairo-last-payload']));
            } else {
                qaTestMode.warnLog('Lütfen önce bir ürün ziyaret ediniz', window.localStorage['vairo-last-payload']);
            }
        };

        window.isApiUpdated = function () {
            if (typeof (Insider || {}).generateTime !== 'undefined') {
                var generateTime = new Date(Insider.generateTime * 1000);
                var now = new Date();
                var hoursDiff = now.getHours() - generateTime.getHours();
                var minDiff = now.getMinutes() - generateTime.getMinutes();

                if (hoursDiff === 0 && minDiff < 10) {
                    return true;
                }
            }

            return false;
        };

        window.useCouponButtonTest = function (coupunCodeFromInsider = '') {
            if (coupunCodeFromInsider !== '') {
                try {
                    if (typeof Insider !== 'undefined') {
                        if (qaTestMode.systemRule.isOnCouponPage()) {
                            Insider.dom(qaTestMode.systemRule.useCouponButton().couponInput).val(coupunCodeFromInsider);
                            console.log('coupon text ', coupunCodeFromInsider);

                            setTimeout(function () {
                                window.eval(qaTestMode.systemRule.useCouponButton().buttonClick);
                            }, 500);
                        }
                    } else if (typeof sQuery !== 'undefined') {
                        sQuery(qaTestMode.systemRule.useCouponButton().couponInput).val(coupunCodeFromInsider);
                        console.log('coupon text ', coupunCodeFromInsider);

                        setTimeout(function () {
                            window.eval(qaTestMode.systemRule.useCouponButton().buttonClick);
                        }, 500);
                    }
                } catch (err) {
                    console.log('Click Error');
                    console.log(err);
                }
            } else {
                console.log('Lütfen kupon kodu giriniz.');
            }
        };

        // Window'a isOnPage fonksiyonunu yazar
        window.isOnPage = function (printGrouped) {
            if (typeof printGrouped === 'undefined') {
                printGrouped = true;
            }

            if (printGrouped) {
                window.console.groupCollapsed('%c' + '# isOnPage()', 'color:gray');
            }

            if (qaTestMode.systemRule.isOnMainPage()) {
                window.console.log('%cisOnMainPage():         ' + '%c' +
                    qaTestMode.systemRule.isOnMainPage(), 'color:blue', 'color:#27CA00; font-weight:bold;');
            } else {
                window.console.log('%cisOnMainPage():         ' + '%c' +
                    qaTestMode.systemRule.isOnMainPage(), 'color:blue', 'font-weight:bold;');
            }

            if (qaTestMode.systemRule.isOnCategoryPage()) {
                window.console.log('%cisOnCategoryPage():     ' + '%c' +
                    qaTestMode.systemRule.isOnCategoryPage(), 'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnCategoryPage():     ' + '%c' +
                    qaTestMode.systemRule.isOnCategoryPage(), 'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnProductPage()) {
                window.console.log('%cisOnProductPage():      ' + '%c' +
                    qaTestMode.systemRule.isOnProductPage(), 'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnProductPage():      ' + '%c' +
                    qaTestMode.systemRule.isOnProductPage(), 'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnCartPage()) {
                window.console.log('%cisOnCartPage():         ' + '%c' +
                    qaTestMode.systemRule.isOnCartPage(), 'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnCartPage():         ' + '%c' + qaTestMode.systemRule.isOnCartPage(),
                    'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnWishlistPage()) {
                window.console.log('%cisOnWishlistPage():         ' + '%c' +
                    qaTestMode.systemRule.isOnWishlistPage(), 'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnWishlistPage():         ' + '%c' + qaTestMode.systemRule.isOnWishlistPage(),
                    'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnCouponPage()) {
                window.console.log('%cisOnCouponPage():       ' + '%c' + qaTestMode.systemRule.isOnCouponPage(),
                    'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnCouponPage():       ' + '%c' + qaTestMode.systemRule.isOnCouponPage(),
                    'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnAfterPaymentPage()) {
                window.console.log('%cisOnAfterPaymentPage(): ' + '%c' + qaTestMode.systemRule.isOnAfterPaymentPage(),
                    'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnAfterPaymentPage(): ' + '%c' + qaTestMode.systemRule.isOnAfterPaymentPage(),
                    'color:blue', 'font-weight: bold;');
            }

            if (qaTestMode.systemRule.isOnRegSuccessPage()) {
                window.console.log('%cisOnRegSuccessPage():   ' + '%c' + qaTestMode.systemRule.isOnRegSuccessPage(),
                    'color:blue', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%cisOnRegSuccessPage():   ' + '%c' + qaTestMode.systemRule.isOnRegSuccessPage(),
                    'color:blue', 'font-weight: bold;');
            }

            if (printGrouped) {
                window.console.groupEnd();
            }

            window.console.log('\n');
        };

        // isOnPage'e _vairo ön eki
        window._vairoIsOnPage = window.isOnPage;
    },
    hitListener: function () {
        this.log('Hit Listener:', 'Initialized');

        /**
         * Hit i payload ile birlikte dinleyebilmek için send
         * tipinde listener oluşturuldu.
         */

        function ajaxListener(callback) {
            if (!this.ajaxListenerInitiated) {
                var originalSendFunction = XMLHttpRequest.prototype.send;

                XMLHttpRequest.prototype.send = function (data) {
                    this.addEventListener('readystatechange', function () {
                        if (this.responseType !== 'arraybuffer' && this.responseType !== 'blob' &&
                            this.readyState === 4 && this.status === 200 && typeof callback === 'function') {
                            try {
                                callback(this.responseURL, data);
                            } catch (error) {
                                qaTestMode.errorLog('ajaxListener', error);
                            }
                        }
                    });

                    originalSendFunction.apply(this, arguments);
                };
            }

            this.ajaxListenerInitiated = true;
        }

        /**
         * Gelen payload ı parse etmek için hitParser çağırılıyor.
         */
        ajaxListener(function (url, payload) {
            if ((url || '').indexOf('hit.api') !== -1) {
                payload = payload.match(/:$/) ? payload.replace(/:$/g, '') : payload;
                try {
                    payload = decodeURIComponent(escape(atob(payload)));
                } catch (e) {}

                qaTestMode.hitParser(payload);
            }
        });
    },
    productEventListener: function () {
        this.log('Events Listener', 'Initialized');

        function ajaxListener(callback) {
            if (!this.eventAjaxListenerInitiated) {
                'use strict';

                var oldSend = XMLHttpRequest.prototype.send;

                XMLHttpRequest.prototype.send = function (data) {
                    this.addEventListener('readystatechange', function () {
                        if (this.responseType !== 'arraybuffer' && this.responseType !== 'blob' &&
                            this.readyState === 4 && this.status === 200 && typeof callback === 'function') {
                            callback(this.responseURL, data);
                        }
                    });

                    oldSend.apply(this, arguments);
                    this.eventAjaxListenerInitiated = true;
                };
            }
        }

        ajaxListener(function (url, payload) {
            if ((url || '').indexOf('/api/event/v1/insert') !== -1) {

                try {
                    payload = JSON.parse(payload || '{}') || {};
                } catch (e) {
                    qaTestMode.errorLog('event payload verisi parse edilemedi!', e);
                }

                qaTestMode.productEventsChecker(payload);
            }
        });
    },
    productEventsChecker: function (payload) {
        payload.events.map(function (event) {
            window.console.log('%cEVENT TRIGGERED!', 'font-size:20px;color:red');
            qaTestMode.warnLog('EVENT NAME', event.event_name);
            window.console.table(event.event_params);
        });
    },
    setLogLevel: function /** Bastırılacak logları filtreler */ ( /** "eswl" */ levelString) {
        if (levelString) {
            var all = 'lsew';

            levelString.split('').forEach(function (letter) {
                all = all.replace(letter, '');
            });
            window.localStorage['vTestLogLevel'] = all;
        } else {
            console.log('%c setLogLevel fonksiyonu logları filtrelemek ve kapatmak için kullanılabilir.',
                'background-color: black; color:khaki; font-weight:bold;');
            console.log('Filtreler:');
            console.log('e', ': Errorları Bastırır');
            console.log('s', ': Successleri Bastırır');
            console.log('w', ': Warning\'leri Bastırır');
            console.log('l', ': Bilgi loglarını bastırır');
            console.log('%c Kullanımı : qaTestMode.setLogLevel("filtre harfleri");',
                'background-color: black; color:khaki; font-weight:bold;');

            console.log('%c Örnek = setLogLevel("el") Error ve Bilgi loglarını bastırır',
                'background-color: black; color:khaki; font-weight:bold;');
            console.log('%c setLogLevel("elws") Tüm logları bastırır',
                'background-color: black; color:khaki; font-weight:bold;');
        }
    },
    log: function (info, result) { // Mor renkli standart logları bastırır
        if ((window.localStorage['vTestLogLevel'] || '').indexOf('l') === -1) {
            console.log('%c ' + info + ':' + '%c ' + ' '.repeat(20 - info.length > 0 ? 20 - info.length : 0) + result,
                'color:#FF00FF;',
                'color:#FF00FF; font-weight:bold;');
        }
    },
    successLog: function (info, result) { // Yeşil renkli success logları bastırır
        if ((window.localStorage['vTestLogLevel'] || '').indexOf('s') === -1) {
            if (typeof result === 'object') {
                console.log('%c ' + info + ':',
                    'font-weight:bold; color:#468641', result);
            } else {
                console.log('%c ' + info + ':' + '%c ' + ' '.repeat(20 - info.length > 0 ? 20 - info.length : 0) +
                    result,
                    'font-weight:bold; color:#468641',
                    'color:#27CA00; font-weight:bold;');
            }
        }
    },
    errorLog: function (info, result) { // Kırmızı renkli error logları bastırır
        if ((window.localStorage['vTestLogLevel'] || '').indexOf('e') === -1) {
            if (typeof result === 'object') {
                console.error('%cErr ' + info + ':',
                    'font-weight:bold; background-color: red; color:white; padding:2px; border-radius:25px;', result);
            } else {
                console.error('%cErr ' + info + ':' + '%c ' + ' '.repeat(20 - info.length > 0 ? 20 - info.length : 0) +
                    result,
                    'font-weight:bold; background-color: maroon; color:lightgrey; padding:5px; border-radius:25px;',
                    'color:#FF00FF; font-weight:bold;');
            }
        }

        var logStack = window.localStorage['vairo-error-logstack'] ?
            JSON.parse(window.localStorage['vairo-error-logstack']) : [];

        try {
            logStack.push({
                info: info || '',
                detail: result || '',
                time: new Date(),
                url: document.location.href || ''
            });
        } catch (error) {
            //console.log(error)
        }

        window.localStorage['vairo-error-logstack'] = JSON.stringify(logStack);
    },
    warnLog: function (info, result) { // Sarı renkli warning logları bastırır
        if ((window.localStorage['vTestLogLevel'] || '').indexOf('w') === -1) {
            if (typeof result === 'object') {
                console.log('%c ' + info + ':', 'background-color: khaki; color:black; padding:2px; border-radius:25px',
                    result);
            } else {
                console.log('%c ' + info + ':%c ' + result,
                    'background-color: khaki; color:black; padding:2px; border-radius:25px',
                    'background-color: khaki; color:black; font-weight:bold; padding:2px; border-radius:25px');
            }
        }

        var gLogStack = window.localStorage['vairo-general-logstack'] ?
            JSON.parse(window.localStorage['vairo-general-logstack']) : [];

        gLogStack.push({
            info: info || '',
            detail: result || '',
            time: new Date(),
            url: document.location.href || ''
        });

        window.localStorage['vairo-general-logstack'] = JSON.stringify(gLogStack);
    },
    hitParser: function (payload) {
        /**
         * -Payload parse edilip bir değişkene atılıyor. 
         * -İçerisinden event ve page_type bilgilerini alınıyor ve
         * bu bilgiler uyan case lere göre check fonksiyonlarına
         * payload bilgisi gönderiliyor.
         */
        function getApiUrl() { // ApiUrl'in tanımlı olup olmadığını kontrol eder
            try {
                return Insider.partner.apiUrl;
            } catch (e) {
                qaTestMode.errorLog('API yüklenirken hata!', e);

                return '';
            }
        }

        try { // Hiti JSON.parse edip testler için işlenecek hale getirmeye çalışır
            var pData = JSON.parse(payload);

            var event = pData['event'] || '';
            var pageType = pData['page_type'] || '';

            // event pageView değilse boşver (Bu sağlıklı bir return kontrolü değil. Yapı değiştirilmeli)
            if (event !== 'pageView') {
                return;
            }

            window.console.log('%c-- HIT CHECKER START --', 'color:white; background-color:black; font-weight:bold;');

            if (window.Insider && (window.Insider.partner || []).apiUrl) { // Yeni API ise
                qaTestMode.warnLog('LAST GENERATE', new Date(Insider.generateTime * 1000));

                console.log('%cPanel Url: %s', 'font-size:18px;font-weight:bold',
                    (window.Insider.partner.apiUrl || []).replace('api', 'inone'));
                window.panelUrlPrinted = true;
            } else if (getApiUrl()) { // Eski API ise
                console.log('%cPanel Url: %s', 'font-size:18px;font-weight:bold',
                    getApiUrl().replace('api', 'inone'));
                window.panelUrlPrinted = true;
            } else {
                console.log('%cPanel Url Bulunamadı %s', 'font-size:18px;font-weight:bold',
                    'window.Insider.partner, spApi.apiUrl, ins.js bilgilerini kontrol edin.');
            }

            setTimeout(function () { // Login, currency, language bilgilerinin değişimini izlemek için storage'a yazar
                window.localStorage['ins-last-login-status'] = qaTestMode.systemRule.isUserLoggedIn().toString();
                window.localStorage['ins-last-currency-status'] = qaTestMode.systemRule.getCurrency();
                window.localStorage['ins-last-language-status'] = qaTestMode.systemRule.getLang();
            }, 1000);

            window.console.log('%c<<<<< HIT Controls >>>>>>', 'color:red; font-weight:bold;');

            var isOnPageControl = this.systemRule.isOnMainPage() + this.systemRule.isOnCategoryPage() +
                this.systemRule.isOnProductPage() + this.systemRule.isOnCartPage() +
                this.systemRule.isOnWishlistPage() + this.systemRule.isOnAfterPaymentPage();

            // isNaN kullanmayın, sağlıklı değil
            // eslint-disable-next-line use-isnan
            if (typeof isOnPageControl !== 'number' || isOnPageControl.toString() === 'NaN') {
                qaTestMode.errorLog('isOnPage kuralı hatalı değer!', 'Boolean dönmeyen isOnPage var!');
            } else if (isOnPageControl > 1) {
                qaTestMode.errorLog('Duplicate isOnPage result', 'Birden fazla true dönen isOnPage var!');
            }

            // isOnAfter'ın hep true gelmesini kontrol eden intervali kapatır
            window._vairoisOnAfterInterval ? clearInterval(window._vairoisOnAfterInterval) : '';

            // pageType'a göre gerekli kontrolleri yapar
            if (pageType === 'category') {
                this.checkgetCategories(pData);
            } else if (pageType === 'productDetail') {
                this.checkgetCurrentProduct(pData);
            } else if (pageType === 'main') {
                this.checkMain(pData);
            } else if (pageType === 'cart') {
                this.checkCart(pData);
            } else if (pageType === 'wishlist') {
                this.checkWishlist(pData);
            } else if (pageType === 'register') {
                this.checkRegister(pData);
            } else if (pageType === 'success') {
                this.checkAfter(pData);
            } else {
                this.errorLog('page_type', pageType);
            }

            // Sepet sayfasında tutarsızlığı kontrol etmek için productList'i storage'da tutar
            if (pageType !== 'cart' && pageType !== 'success' && window.localStorage.getItem('ins-cart-product-list')) {
                var sData = (qaTestMode.parseJSON(localStorage.getItem('ins-cart-product-list')) || []).data ||
                    qaTestMode.parseJSON(localStorage['ins-cart-product-list']).data || [];
                var insStorage = typeof sData === 'object' ? sData :
                    qaTestMode.parseJSON(sData);

                window.localStorage['vTest-last-product-list'] = JSON.stringify(insStorage.productList);
            }

            // wishlist sayfasında tutarsızlığı kontrol etmek için productList'i storage'da tutar
            if (pageType !== 'wishlist' && window.localStorage.getItem('ins-wishlist-product-list')) {
                var wishlistData = (qaTestMode.parseJSON(localStorage.getItem('ins-wishlist-product-list')) || [])
                    .data || qaTestMode.parseJSON(localStorage['ins-wishlist-product-list']).data || [];
                var insWisStorage = typeof wishlistData === 'object' ? wishlistData :
                    qaTestMode.parseJSON(wishlistData);

                window.localStorage['vTest-last-wishlist-product-list'] = JSON.stringify(insWisStorage.productList);
            }

            /**
             * - checkLangAndCurrency -
             * Language ve currency fonksiyonları her hit
             * geldiğinde kontrol edilecek şekilde ayarlandı.
             * 
             * - checkTotal -
             * cart count ve total amount u içerir.
             * 
             * - checkSearch -
             * getSearchKeyWords ü kontrol eder.
             * Eğer arama sayfası dışında false döndürmezse
             * hata basar.
             * 
             */
            this.checkLangAndCurrency();

            // storage'dan currency değişim kontrolü
            if (window.localStorage['ins-last-currency-status'] && window.localStorage['ins-last-currency-status'] !==
                qaTestMode.systemRule.getCurrency()) {
                qaTestMode.warnLog('Currency değişti!',
                    window.localStorage['ins-last-currency-status'] + ' => ' + qaTestMode.systemRule.getCurrency());
            }

            // storage'dan dil değişim kontrolü
            if (window.localStorage['ins-last-language-status'] && window.localStorage['ins-last-language-status'] !==
                qaTestMode.systemRule.getLang()) {
                qaTestMode.warnLog('Dil değişti!',
                    window.localStorage['ins-last-language-status'] + ' => ' + qaTestMode.systemRule.getLang());
            }

            this.checkTotals(pData);
            this.checkSearch(pData);
            this.checkLogin();

            // storage'dan login değişim kontrolü
            if (window.localStorage['ins-last-login-status'] && window.localStorage['ins-last-login-status'] !==
                qaTestMode.systemRule.isUserLoggedIn().toString()) {
                qaTestMode.warnLog('Login durumu değişti!',
                    window.localStorage['ins-last-login-status'] + ' => ' + qaTestMode.systemRule.isUserLoggedIn());
            }

            //Error bag'leri bastırır.
            if (typeof Insider !== 'undefined' && typeof (Insider.errorBag || {})._errors !== 'undefined' &&
                ((Insider.errorBag || {})._errors || []).length > 0) {
                qaTestMode.errorLog('ERROR BAG DOLU!', (Insider.errorBag || {})._errors);
            }

            this.checkCoupon();

            // HIT ile birlikte storage bilgisini bastırır
            try {
                qaTestMode._vairoDumpStorage();
            } catch (storageError) {
                console.log('%c Storage Read/Write Error!', 'color:red; font-weight:bold', storageError);
            }

            console.log('%c HIT', 'font-size: 15px;', pData);

            window.console.log('%c-- HIT CHECKER END --', 'color:white; background-color:black; font-weight:bold;');
        } catch (e) {
            this.errorLog('Invalid HIT payload', e, payload);
        }
    },
    checkgetCategories: function (payload) {
        /**
         * -Kategori sayfalarında kategori bilgisinin boş olup 
         * olmadığını ve tip durumlarını kontrol ediyor.
         * -Konsola tüm kategori datasını basıyor ve değerlerin
         * rahat bir şekilde görülmesi sağlanıyor.
         * -Hatalı bir değer algılanırsa konsola basılan
         * kategori değerleri kırmızı ile işaretleniyor.
         */

        // else'ini başka yerde(hitParser satır 439, isOnPageControl) zaten bastırıyoruz
        if (this.systemRule.isOnCategoryPage() &&
            !(this.systemRule.isOnAfterPaymentPage() &&
                this.systemRule.isOnProductPage() &&
                this.systemRule.isOnCartPage() &&
                this.systemRule.isOnMainPage())) {
            this.successLog('HIT page_type', payload['page_type']);
        }

        var categories = payload['category'];

        if (typeof categories === 'object') {
            for (var i = 0; i < categories.length; i++) {
                if (!(categories[i] !== '' && typeof categories[i] === 'string')) {
                    this.errorLog('getCategories[' + i + ']', categories[i]);
                }
            }
            this.successLog('getCategories()', '\n          ' + (categories || []).join('\n          '));

            var lastCategories = {
                referrer: window.location.href,
                cats: categories
            };

            window.localStorage['vTest_last_category'] = JSON.stringify(lastCategories);
        }
    },
    systemRule: new Proxy({}, { // tekrar tekrar fallback vermeden yeni api ve eski api kodlarını aynı şekilde çağır
        get: function (target, prop) { // systemRule.bilmemne => target.prop çağırıldığında aşağıdakini yap
            if (target[prop] === undefined) {
                return function () {
                    if (window.Insider) {
                        return Insider.systemRules.call(prop);
                    } else if ((window.spApi || []).addGoalTracking) {
                        return (window.spApi || [])[prop]();
                    }
                };
            }

            return target[prop];
        }
    }),
    checkgetCurrentProduct: function (payload) {
        /**
         * -Ürün sayfası kontrolü yapılıyor ve Hit içerisinden
         * veriler alınarak verilerin tip ve değer kontrolleri
         * yapılıyor.
         * -getCurrentProduct kuralı içerisinde bulunan tüm
         * attribute ler teker teker kontrol edilerek konsola
         * bastırılıyor.
         */
        if (this.systemRule.isOnProductPage() &&
            !(this.systemRule.isOnAfterPaymentPage() &&
                this.systemRule.isOnCategoryPage() &&
                this.systemRule.isOnCartPage() &&
                this.systemRule.isOnMainPage())) {
            this.successLog('HIT page_type', payload['page_type']);
        }

        var product = payload['product'];
        var currentProductSystemRule = qaTestMode.systemRule.getCurrentProduct();

        // ID Kontrol
        // String ve boş olup olmadığı kontrolü
        if (typeof product['id'] === 'string' && product['id'] !== '') {
            this.successLog('id', product['id']);
        } else {
            this.errorLog('id', product['id'] + ' TYPE: boş yada int');
        }

        // Name Kontrol
        // String ve boş olup olmadığı kontrolü
        if (typeof product['name'] === 'string' && product['name'] !== '') {
            this.successLog('name', product['name']);
        } else {
            this.errorLog('name', product['name'] + ' :boş');
        }

        // Price & Original price Kontrol
        // Number olduğu ve 0 olmadığı kontrolü
        if (typeof product['price'] === 'object' &&
            typeof Object.values(product['price'])[0] === 'number' &&
            typeof Object.values(product['price'])[2] === 'number' &&
            Object.values(product['price'])[0] !== 0 &&
            Object.values(product['price'])[2] !== 0) {
            var isExchanged = (currentProductSystemRule['exchange'] || '').split('to').pop().trim() !==
                (currentProductSystemRule['exchange'] || '').split('to').shift().replace('from', '').trim();

            if (Object.values(product['price'])[0] > Object.values(product['price'])[2] && !isExchanged) {
                this.errorLog('price', Object.values(product['price'])[0] + ' :price > originalPrice');
                this.errorLog('originalPrice', Object.values(product['price'])[2] + ' :originalPrice < price');
            } else {
                this.successLog('price', Object.values(product['price'])[0]);
                this.successLog('originalPrice', Object.values(product['price'])[2]);
            }

        } else if (Object.values(product['price'])[0] === 0 && Object.values(product['price'])[2] === 0) {
            this.warnLog('price', Object.values(product['price'])[0]);
            this.warnLog('originalPrice', Object.values(product['price'])[0]);
        } else {
            if (Object.values(product['price'])[0] === 0) {
                qaTestMode.warnLog('price', 0);
            } else {
                qaTestMode.errorLog('price', Object.values(product['price'])[0] + ' Number değil!');
            }

            if (Object.values(product['price'])[2] === 0) {
                qaTestMode.warnLog('originalPrice', 0);
            } else if (Object.values(product['price'])[0] !== 0) {
                qaTestMode.errorLog('originalPrice', Object.values(product['price'])[2] + ' Number değil!');
            }
        }

        if (currentProductSystemRule.hasOwnProperty('notConvertedPrice')) {
            this.successLog('notConvertedPrice', currentProductSystemRule['notConvertedPrice']);
        }

        // Image Kontrol
        // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
        if (typeof product['imgUrl'] === 'string' && product['imgUrl'].indexOf('http') === 0 &&
            product['imgUrl'] !== '') {
            this.successLog('img', product['imgUrl']);
            window.console.log('%c   ', 'font-size: 50px; background: url(' + product['imgUrl'] +
                ') no-repeat center center; height: 100px; background-size: contain;');
        } else {
            this.errorLog('img', product['imgUrl'] + '\n boş, protokol içermiyor yada string değil ');
        }

        // URL Kontrol
        // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
        if (typeof product['url'] === 'string' && product['url'].indexOf('http') === 0 &&
            product['url'] !== '') {
            this.successLog('url', product['url']);
        } else {
            this.errorLog('url', product['url'] + '\n boş, protokol içermiyor yada string değil ');
        }

        // Quantity Kontrol
        // Number olduğu ve 0 olmadığı kontrolü
        if (!product.hasOwnProperty('quantity')) {
            this.warnLog('HIT Quantity', 'HIT içerisinde quantity alanı bulunmuyor.');
        } else {
            if (typeof product['quantity'] === 'number' && product['quantity'] !== 0) {
                this.successLog('quantity', product['quantity']);
            } else if (product['quantity'] === 0) {
                this.warnLog('quantity', 0);
            } else {
                this.errorLog('quantity', product['quantity'] + ' Number değil!');
            }
        }

        // Variant kontrolü
        // Tipi array mi, içerisinde getCurrentProduct().id var mı
        if (product.hasOwnProperty('variants')) {
            if (product['variants'] instanceof Array) {
                if (product['variants'].indexOf(product['id']) !== -1) {
                    this.errorLog('Product ID variants içerisinde', product['id']);
                    this.warnLog('Variants', product['variants']);
                } else {
                    this.successLog('variants', product['variants']);
                }
            } else {
                this.errorLog('variants Array değil', product['variants']);
            }
        }

        if (currentProductSystemRule.hasOwnProperty('product_attributes')) {
            this.successLog('product_attributes', currentProductSystemRule['product_attributes']);
        }

        if (currentProductSystemRule.hasOwnProperty('groupcode')) {
            this.successLog('groupcode', currentProductSystemRule['groupcode']);
        }

        if (typeof product['updateDate'] === 'number' && (product['updateDate'] || '') !== '') {
            qaTestMode.successLog('updateDate', product['updateDate']);
        }

        if (currentProductSystemRule.hasOwnProperty('exchange')) {
            this.successLog('exchange', currentProductSystemRule['exchange']);
        }

        this.checkProductCategories(payload);

        // _vairoSpAddLast için ürün bilgilerini storage'a yazar
        window.localStorage['vairo-last-payload'] = window._vairoGetPayload();
        window.localStorage['vairo-last-id'] = (this.systemRule.getCurrentProduct() || []).id;
    },
    checkProductCategories: function (payload) {
        var categories = payload['product']['category'];

        if (typeof categories === 'undefined') {
            return this.warnLog('getCurrentProduct() kuralı içerisinde cats bulunmuyor.');
        }

        // Kategorilerin veri tipini ve doluluğunu kontrol eder.
        if (typeof categories === 'object') {
            for (var i = 0; i < categories.length; i++) {

                if (!categories[i] || typeof categories[i] !== 'string') {
                    this.errorLog('getProductCategories[' + i + ']', categories[i]);
                }
            }

            this.successLog('getProductCategories()', '\n          ' + (categories || []).join('\n          '));
        }

        // Son kategori sayfasındaki kategori ile takip eden ürün sayfası arasında uyum kontrolü
        if (window.localStorage['vTest_last_category']) {
            var lastCats = qaTestMode.parseJSON(window.localStorage['vTest_last_category']);

            if (document.referrer === lastCats.referrer) {
                var catsMatch = (categories || []).reduce(function (sum, cat) {
                    return lastCats.cats.indexOf(cat) !== -1 || lastCats.cats.indexOf(cat) !== -1 || sum;
                }, false);

                if (!catsMatch) {
                    this.warnLog('getCategories() ile getProductCategories() arasında ortak kategori bulunmuyor', {
                        getProductCategories: categories,
                        getCategories: lastCats.cats
                    });
                }
            }
        }

        // Ürün isminin kategoriler arasında bulunup bulunmadığı
        if ((payload['product']['name'] || '').replace(/[^A-Za-z]/g, '').toLowerCase().indexOf(
                (((categories || []).slice(-1) || [])[0] || '').replace(/[^A-Za-z]/g, '').toLowerCase()) &&
            !(((categories || []).slice(-1) || [])[0] || '').replace(/[^A-Za-z]/g, '')) {
            this.warnLog('Ürün ismi kategoriler arasında', payload['product']['name']);
        }

        // Tekrarlayan kategori olup olmadığı kontrolü
        (categories || []).filter(function (value, index) {
            categories.indexOf(value) !== index ? qaTestMode.warnLog('Tekrarlayan kategori', value) : '';
        });
    },
    checkMain: function (payload) {
        /**
         * Hit parse içerisinde zaten page_type kontrollerimiz
         * vardı. Oradan gelen page_type ın main olması ile
         * isOnMainPage in true olması kontrolü yapılıyor.
         */
        if (this.systemRule.isOnMainPage()) {
            this.successLog('HIT page_type', payload['page_type']);
        } else {
            this.errorLog('isOnMainPage false', 'Hit içerisinde true');
        }
    },
    checkTotals: function (payload) {
        this.log('HIT Total', payload['cart_amount']);

        if (this.systemRule.getTotalCartAmount() !== parseFloat(payload['cart_amount'])) {
            this.errorLog('getTotalCartAmount()', 'HIT cart_amount ile uyuşmuyor. ' +
                this.systemRule.getTotalCartAmount() + ' => ' + payload['cart_amount']);
        } else if (this.systemRule.getTotalCartAmount() === 0 && this.systemRule.getCartCount() > 0) {
            this.errorLog('getCartCount()', '0 dan büyük ancak getTotalCartAmount 0');
        } else {
            this.successLog('getTotalCartAmount()', this.systemRule.getTotalCartAmount());
        }

        if (((payload['cart_amount'] || '').toString().split('.')[1] || '').length > 2) {
            this.errorLog('getTotalCartAmount() toFixed değil!', payload['cart_amount']);
        }

        if (typeof this.systemRule.getTotalCartAmount() !== 'number') {
            this.errorLog('getTotalCartAmount()', 'number değil');
        }

        if (this.systemRule.getCartCount() === 0 && this.systemRule.getTotalCartAmount() > 0) {
            this.errorLog('getTotalCartAmount()', '0 dan büyük ancak getCartCount 0');
        } else if (typeof this.systemRule.getCartCount() !== 'number') {
            this.errorLog('getCartCount()', 'Number Değil');
        } else {
            this.successLog('getCartCount()', this.systemRule.getCartCount());
        }
    },
    checkCart: function (payload) {
        /**
         * -Sepet sayfası full kontrolü yapılıyor.
         */
        if (this.systemRule.isOnCartPage() &&
            !(this.systemRule.isOnAfterPaymentPage() &&
                this.systemRule.isOnProductPage() &&
                this.systemRule.isOnCategoryPage() &&
                this.systemRule.isOnMainPage())) {
            this.successLog('HIT page_type', payload['page_type']);
        }

        var products = payload['products'] || [];
        var idList = [];

        if (products.length < 0) {
            this.errorLog('HIT', 'products boş');
        }

        var latestProductList = window.localStorage['vTest-last-product-list'] ?
            qaTestMode.parseJSON(window.localStorage['vTest-last-product-list']) : 'notAvailable';

        products.forEach(function (product) {
            console.groupCollapsed('ID : ' + product.id);

            if (idList.indexOf(product.id) !== -1) {
                qaTestMode.errorLog('id', product['id'] + ' :Gruplanmamış Id');
            }

            idList.push(product.id);

            // ID Kontrol
            // String ve boş olup olmadığı kontrolü
            if (typeof product['id'] === 'string' && product['id'] !== '') {
                qaTestMode.successLog('id', product['id']);
            } else {
                qaTestMode.errorLog('id', product['id'] + ' :boş yada int');
            }

            // Name Kontrol
            // String ve boş olup olmadığı kontrolü
            if (typeof product['name'] === 'string' && product['name'] !== '') {
                qaTestMode.successLog('name', product['name']);
            } else {
                qaTestMode.errorLog('name', product['name'] + ' :boş');
            }

            // Price & Original price Kontrol
            // Number olduğu ve 0 olmadığı kontrolü
            if (typeof product['price'] === 'object' &&
                typeof Object.values(product['price'])[0] === 'number' &&
                typeof Object.values(product['price'])[2] === 'number' &&
                Object.values(product['price'])[0] !== 0 &&
                Object.values(product['price'])[2] !== 0) {
                qaTestMode.successLog('price', Object.values(product['price'])[0]);
                qaTestMode.successLog('originalPrice', Object.values(product['price'])[2]);
            } else {
                if (Object.values(product['price'])[0] === 0) {
                    qaTestMode.warnLog('price', 0);
                } else {
                    qaTestMode.errorLog('price', Object.values(product['price'])[0] + ' Number değil!');
                }

                if (Object.values(product['price'])[2] === 0) {
                    qaTestMode.warnLog('originalPrice', 0);
                } else {
                    qaTestMode.errorLog('originalPrice', Object.values(product['price'])[2] + ' Number değil!');
                }
            }

            // Image Kontrol
            // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
            if (typeof product['imgUrl'] === 'string' && product['imgUrl'].indexOf('http') === 0 &&
                product['imgUrl'] !== '') {
                qaTestMode.successLog('img', product['imgUrl']);
                window.console.log('%c   ', 'font-size: 50px; background: url(' + product['imgUrl'] +
                    ') no-repeat center center; height: 100px; background-size: contain;');
            } else {
                qaTestMode.errorLog('img', product['imgUrl'] + '\n boş, protokol içermiyor yada string değil ');
            }

            // URL Kontrol
            // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
            if (typeof product['url'] === 'string' && product['url'].indexOf('http') === 0 &&
                product['url'] !== '') {
                qaTestMode.successLog('url', product['url']);
            } else {
                qaTestMode.errorLog('url', product['url'] + '\n boş, protokol içermiyor yada string değil ');
            }

            // Quantity Kontrol
            // Number olduğu ve 0 olmadığı kontrolü
            if (!product.hasOwnProperty('quantity')) {
                qaTestMode.warnLog('HIT Quantity', 'HIT içerisinde quantity alanı bulunmuyor.');
            } else {
                if (typeof product['quantity'] === 'number' && product['quantity'] !== 0) {
                    qaTestMode.successLog('quantity', product['quantity']);
                } else {
                    qaTestMode.errorLog('quantity', product['quantity'] + '\n 0 yada number değil');
                }
            }
            console.groupEnd();

            // Sepette son storage ile paid karşılaştırması
            if (latestProductList !== 'notAvailable' && latestProductList) {
                var previousProductInfo = latestProductList.reduce(function (sum, _product) {
                    return _product.id === product.id ? _product : sum;
                }, false);

                if (previousProductInfo) {
                    var previousProductName = '';
                    var productName = '';

                    try {
                        previousProductName = decodeURIComponent(previousProductInfo.name);
                        productName = decodeURIComponent(product.name);
                    } catch (err) {
                        previousProductName = previousProductInfo.name;
                        productName = product.name;
                        qaTestMode.warnLog('Encode-Decode Problemi', err);
                    }

                    previousProductName !== productName ?
                        qaTestMode.errorLog('Storage-getPaid İsim Uyuşmazlığı',
                            previousProductInfo.name + ' !== ' + product.name) : '';
                    previousProductInfo.price !== Object.values(product['price'])[0] ?
                        qaTestMode.errorLog('Storage-getPaid Price Uyuşmazlığı', previousProductInfo.price + ' !== ' +
                            Object.values(product['price'])[0]) : '';
                } else if (latestProductList[0]) {
                    qaTestMode.warnLog('Ürün Storage\'a Sepette Eklendi', product);
                    qaTestMode.warnLog('Olası Sebebi', 'Storage taşınırken ID Uyuşmazlığı olabilir');
                    qaTestMode.warnLog('Olası Sebebi', 'triggerCart\'ın yakalayamadığı ürün eklenmesi olabilir');
                }
            }

        });

        window.localStorage['vTest-last-product-list'] = null;
    },
    checkWishlist: function (payload) {
        /**
         * -wishlist sayfası full kontrolü yapılıyor.
         */
        if (this.systemRule.isOnWishlistPage() &&
            !(this.systemRule.isOnCartPage() ||
                this.systemRule.isOnAfterPaymentPage() &&
                this.systemRule.isOnProductPage() &&
                this.systemRule.isOnCategoryPage() &&
                this.systemRule.isOnMainPage())) {
            this.successLog('HIT page_type', payload['page_type']);
        }

        var products = payload['products'] || [];
        var idList = [];

        if (products.length < 0) {
            this.errorLog('HIT', 'products boş');
        }

        var latestProductList = window.localStorage['vTest-last-wishlist-product-list'] ?
            qaTestMode.parseJSON(window.localStorage['vTest-last-wishlist-product-list']) : 'notAvailable';

        products.forEach(function (product) {
            console.groupCollapsed('ID : ' + product.id);

            if (idList.indexOf(product.id) !== -1) {
                qaTestMode.errorLog('id', product['id'] + ' :Gruplanmamış Id');
            }

            idList.push(product.id);

            // ID Kontrol
            // String ve boş olup olmadığı kontrolü
            if (typeof product['id'] === 'string' && product['id'] !== '') {
                qaTestMode.successLog('id', product['id']);
            } else {
                qaTestMode.errorLog('id', product['id'] + ' :boş yada int');
            }

            // Name Kontrol
            // String ve boş olup olmadığı kontrolü
            if (typeof product['name'] === 'string' && product['name'] !== '') {
                qaTestMode.successLog('name', product['name']);
            } else {
                qaTestMode.errorLog('name', product['name'] + ' :boş');
            }

            // Price & Original price Kontrol
            // Number olduğu ve 0 olmadığı kontrolü
            if (typeof product['price'] === 'object' &&
                typeof Object.values(product['price'])[0] === 'number' &&
                typeof Object.values(product['price'])[2] === 'number' &&
                Object.values(product['price'])[0] !== 0 &&
                Object.values(product['price'])[2] !== 0) {
                qaTestMode.successLog('price', Object.values(product['price'])[0]);
                qaTestMode.successLog('originalPrice', Object.values(product['price'])[2]);
            } else {
                if (Object.values(product['price'])[0] === 0) {
                    qaTestMode.warnLog('price', 0);
                } else {
                    qaTestMode.errorLog('price', Object.values(product['price'])[0] + ' Number değil!');
                }

                if (Object.values(product['price'])[2] === 0) {
                    qaTestMode.warnLog('originalPrice', 0);
                } else {
                    qaTestMode.errorLog('originalPrice', Object.values(product['price'])[2] + ' Number değil!');
                }
            }

            // Image Kontrol
            // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
            if (typeof product['imgUrl'] === 'string' && product['imgUrl'].indexOf('http') === 0 &&
                product['imgUrl'] !== '') {
                qaTestMode.successLog('img', product['imgUrl']);
                window.console.log('%c   ', 'font-size: 50px; background: url(' + product['imgUrl'] +
                    ') no-repeat center center; height: 100px; background-size: contain;');
            } else {
                qaTestMode.errorLog('img', product['imgUrl'] + '\n boş, protokol içermiyor yada string değil ');
            }

            // URL Kontrol
            // String ve boş olmadığı ayrıca protocol içerdiği kontrolü
            if (typeof product['url'] === 'string' && product['url'].indexOf('http') === 0 &&
                product['url'] !== '') {
                qaTestMode.successLog('url', product['url']);
            } else {
                qaTestMode.errorLog('url', product['url'] + '\n boş, protokol içermiyor yada string değil ');
            }

            // Quantity Kontrol
            // Number olduğu ve 0 olmadığı kontrolü
            if (!product.hasOwnProperty('quantity')) {
                qaTestMode.warnLog('HIT Quantity', 'HIT içerisinde quantity alanı bulunmuyor.');
            } else {
                if (typeof product['quantity'] === 'number' && product['quantity'] !== 0) {
                    qaTestMode.successLog('quantity', product['quantity']);
                } else {
                    qaTestMode.errorLog('quantity', product['quantity'] + '\n 0 yada number değil');
                }
            }
            console.groupEnd();

            // Sepette son storage ile paid karşılaştırması
            if (latestProductList !== 'notAvailable' && latestProductList) {
                var previousProductInfo = latestProductList.reduce(function (sum, _product) {
                    return _product.id === product.id ? _product : sum;
                }, false);

                if (previousProductInfo) {
                    var previousProductName = '';
                    var productName = '';

                    try {
                        previousProductName = decodeURIComponent(previousProductInfo.name);
                        productName = decodeURIComponent(product.name);
                    } catch (err) {
                        previousProductName = previousProductInfo.name;
                        productName = product.name;
                        qaTestMode.warnLog('Encode-Decode Problemi', err);
                    }

                    previousProductName !== productName ?
                        qaTestMode.errorLog('Storage-getWishlist İsim Uyuşmazlığı',
                            previousProductInfo.name + ' !== ' + product.name) : '';
                    previousProductInfo.price !== Object.values(product['price'])[0] ?
                        qaTestMode.errorLog('Storage-getWishlist Price Uyuşmazlığı',
                            previousProductInfo.price + ' !== ' + Object.values(product['price'])[0]) : '';
                } else if (latestProductList[0]) {
                    qaTestMode.warnLog('Ürün Storage\'a Wishlist de Eklendi', product);
                    qaTestMode.warnLog('Olası Sebebi', 'Storage taşınırken ID Uyuşmazlığı olabilir');
                    qaTestMode.warnLog('Olası Sebebi', 'triggerWishlist\'in yakalayamadığı ürün eklenmesi olabilir');
                }
            }

        });

        window.localStorage['vTest-last-wishlist-product-list'] = null;
    },
    checkSearch: function (payload) { // getSearchKeywords kontrolleri
        if (payload['page_type'] !== 'other' && typeof payload['search_query'] === 'string') {
            this.errorLog('getSearchKeywords()', 'Search yapılmadı ancak search_query Hit te dolu gidiyor.');
            this.errorLog('Search Query Payload', payload['search_query']);
            this.errorLog('getSearchKeyWords', this.systemRule.getSearchKeyWords());
        } else if (typeof payload['search_query'] === 'string') {
            if (payload['search_query'] === decodeURIComponent(payload['search_query'])) {
                this.successLog('Search Query Payload', payload['search_query']);
                this.successLog('getSearchKeyWords', this.systemRule.getSearchKeyWords());
            } else {
                this.errorLog('Search Query Payload', payload['search_query']);
                this.errorLog('getSearchKeyWords', 'Decoded Değil!');
            }
        }
    },
    checkLangAndCurrency: function () {
        /**
         * Her HIT gittiği anda kurallar konsola basılacak.
         */
        if (this.systemRule.getLang() !== '') {
            this.log('getLang()', this.systemRule.getLang());
        } else {
            this.errorLog('getLang()', this.systemRule.getLang());
        }

        if (this.systemRule.getCurrency() !== '') {
            this.log('getCurrency()', this.systemRule.getCurrency());
        } else {
            this.errorLog('getCurrency()', this.systemRule.getCurrency());
        }
    },
    checkRegister: function (payload) {
        /**
         * Payload page_type kontrolü Hit parser
         * içerisinde yapılıyor. Burada tek yaptığımız
         * isOnRegSuccessPage in doğruluğunu kontrol etmke
         */
        if (this.systemRule.isOnRegSuccessPage()) {
            this.successLog('isOnRegSuccessPage()', 'Ok!');
        } else {
            this.errorLog('isOnRegSuccessPage()', this.systemRule.isOnRegSuccessPage());
            this.errorLog('HIT page_type', payload.page_type);
        }
    },
    checkAfter: function (payload) {
        /**
         * isOnAfterPaymentPage ve getOrderId kontolü.
         */
        if (this.systemRule.isOnAfterPaymentPage()) {
            this.successLog('isOnAfterPaymentPage()', 'true');
        } else {
            this.errorLog('HIT page_type', payload.page_type);
        }

        /**
         * getOrderId nin boş ya da undefined olmamasını ve 
         * payload ile uyuşmasını kontrol eder.
         */
        if (this.systemRule.getOrderId() === payload.order_id &&
            payload.order_id !== '' && typeof payload.order_id !== 'undefined') {
            this.successLog('getOrderId', this.systemRule.getOrderId());
            this.successLog('HIT order_id', payload.order_id);
        } else {
            this.errorLog('getOrderId', this.systemRule.getOrderId());
            this.errorLog('HIT order_id', payload.order_id);
        }

        // success sayfasında afterPayment'ın hep true olup olmadığını kontrol eder. İkinci bir hitte sıfırlanır
        window._vairoisOnAfterInterval = setInterval(function () {
            if (!qaTestMode.systemRule.isOnAfterPaymentPage()) {
                qaTestMode.errorLog('isOnAfter değişti', qaTestMode.systemRule.isOnAfterPaymentPage());
            }
        }, 500);

        /**
         * paid-products kontrolü
         * 
         */
        var sData = (qaTestMode.parseJSON(localStorage.getItem('ins-cart-product-list')) || []).data ||
            qaTestMode.parseJSON(localStorage['ins-cart-product-list']).data || [];
        var insStorage = typeof sData === 'object' ? sData :
            qaTestMode.parseJSON(sData);

        // afterPayment paid-products kontrolü
        if (payload.products instanceof Array && payload.products[0]) {
            console.group('paid-products');
            for (var prop in payload.products[0]) {
                if (typeof payload.products[0][prop] === 'object') {
                    console.log('%c' + prop + ':', 'color:#468641;', payload.products[0][prop]);
                } else {
                    console.log('%c' + prop + ': %c' + payload.products[0][prop],
                        'color:#468641;', 'color:#27CA00; font-weight:bold;');
                }

            }
            console.groupEnd('paid-products');
        } else {
            qaTestMode.errorLog('paid-products', 'Boş');
        }

        // afterPayment ins-cart-product-list kontrolü
        if (insStorage.productList instanceof Array && insStorage.productList[0]) {
            console.groupCollapsed('ins-cart-product-list');
            for (var _prop in insStorage.productList[0]) {
                if (typeof insStorage.productList[0][_prop] === 'object') {
                    console.log('%c' + _prop + ':', 'color:#468641;', insStorage.productList[0][_prop]);
                } else {
                    console.log('%c' + _prop + ': %c' + insStorage.productList[0][_prop],
                        'color:#468641;', 'color:#27CA00; font-weight:bold;');
                }
            }
            console.groupEnd('ins-cart-product-list');
        } else {
            qaTestMode.errorLog('ins-cart-product-list', 'Boş');
        }
    },
    checkLogin: function () {
        /**
         * isUserLoggedIn check
         */
        if (this.systemRule.isUserLoggedIn()) {
            this.successLog('isUserLoggedIn', 'true');
        } else {
            this.log('isUserLoggedIn', 'false');
        }
    },
    checkCoupon: function () {
        /**
         * isOnCouponPage ve useCouponButton kontrolü
         * yapar.
         */
        if (this.systemRule.isOnCouponPage() === true) {
            this.successLog('isOnCouponPage', true);
            var SELECTORBUTTON = {};
            var SELECTORINPUT = {};

            try {
                SELECTORBUTTON = document.querySelectorAll(this.systemRule.useCouponButton().button);
                SELECTORINPUT = document.querySelectorAll(this.systemRule.useCouponButton().couponInput);

                if (SELECTORBUTTON.length > 0) {
                    this.successLog('useCouponButton button', 'exists');
                } else {
                    this.errorLog('useCouponButton button', 'not exists');
                }

                if (SELECTORINPUT.length > 0) {
                    this.successLog('useCouponButton couponInput', 'exists');
                } else {
                    this.errorLog('useCouponButton couponInput', 'not exists');
                }
            } catch (err) {
                //Empty
            } finally {
                if (typeof window.Insider !== 'undefined') {
                    SELECTORBUTTON = Insider.dom(this.systemRule.useCouponButton().button);
                    SELECTORINPUT = Insider.dom(this.systemRule.useCouponButton().couponInput);
                } else if (typeof window.sQuery !== 'undefined') {
                    SELECTORBUTTON = sQuery(this.systemRule.useCouponButton().button);
                    SELECTORINPUT = sQuery(this.systemRule.useCouponButton().couponInput);
                } else if (typeof window.$ !== 'undefined') {
                    SELECTORBUTTON = window.$(this.systemRule.useCouponButton().button);
                    SELECTORINPUT = window.$(this.systemRule.useCouponButton().couponInput);
                } else {
                    SELECTORBUTTON = [];
                    SELECTORINPUT = [];
                }

                if (SELECTORBUTTON.length > 0) {
                    this.successLog('useCouponButton button', 'exists');
                } else {
                    this.errorLog('useCouponButton button', 'not exists');
                }

                if (SELECTORINPUT.length > 0) {
                    this.successLog('useCouponButton couponInput', 'exists');
                } else {
                    this.errorLog('useCouponButton couponInput', 'not exists');
                }
            }
        }
    },
    testStorage: function (insStorage) { // storage'daki ürün bilgilerini ve total, count'u test eder
        if (!insStorage) {
            var sData = (qaTestMode.parseJSON(localStorage.getItem('ins-cart-product-list')) || []).data ||
                qaTestMode.parseJSON(localStorage['ins-cart-product-list']).data || [];

            insStorage = typeof sData === 'object' ? sData :
                qaTestMode.parseJSON(sData);
        }

        var _totalTest = 0;
        var _countTest = 0;

        window.console.groupCollapsed('%cInsider Storage | Count : %d', 'font-size:20px;',
            parseInt(insStorage.totalQuantity));

        // storage'daki ürünleri bastır
        if (insStorage.productList) {
            insStorage.productList.forEach(function (value, index) {
                window.console.groupCollapsed('%cItem %d :', 'font-weight:bold;font-size:16px',
                    parseInt(index));
                Object.keys(value).forEach(function (val) {
                    window.console.info('%c%s:%c %s', 'color:red;font-weight:bold', val, '', value[val]);
                });

                _totalTest = _totalTest + (value['price'] * value['quantity']);
                _countTest = _countTest + value['quantity'];
                window.console.groupEnd();
            });
        } else {
            qaTestMode.errorLog('ins-cart-product-list hatalı', insStorage);
            window.console.groupEnd();
        }

        if (_totalTest !== this.systemRule.getTotalCartAmount()) {
            this.warnLog('getTotalCartAmount()', 'Storage total farklı');
        }

        if (_countTest !== this.systemRule.getCartCount()) {
            this.errorLog('getCartCount()', 'Storage count farklı');
        }

        window.console.groupEnd();

        window.console.table(insStorage.productList);

        // storage'daki ürünlerin attribute'lerini kontrol eder
        insStorage.productList.forEach(function (value) {
            Object.keys(value).forEach(function (val) {

                if (val === 'id') {
                    if (typeof value[val] !== 'string' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da string değil', val);
                    }
                } else if (val === 'name') {
                    if (typeof value[val] !== 'string' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da string değil', val);
                    }
                } else if (val === 'price') {
                    if (typeof value[val] !== 'number' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da number değil', val);
                    }
                } else if (val === 'originalPrice') {
                    if (typeof value[val] !== 'number' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da number değil', val);
                    }
                } else if (val === 'img') {
                    if (typeof value[val] !== 'string' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da string değil', val);
                    }
                } else if (val === 'url') {
                    if (typeof value[val] !== 'string' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da string değil', val);
                    }
                } else if (val === 'quantity') {
                    if (typeof value[val] !== 'number' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da number değil', val);
                    }
                } else if (val === 'time') {
                    if (typeof value[val] !== 'number' || !value[val]) {
                        qaTestMode.errorLog('Boş ya da number değil', val);
                    }
                } else {
                    if (val === 'exchange' || val === 'notConvertedPrice') {
                        qaTestMode.log('Exchange fonksiyonu', 'Aktif');
                    } else {
                        qaTestMode.errorLog('Geçersiz Storage Anahtarı', val);
                    }
                }
            });

            // storage'daki attribute'ların eksik olup olmadığını kontrol eder
            if (!value.hasOwnProperty('time')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'time');
            } else if (!value.hasOwnProperty('quantity')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'quantity');
            } else if (!value.hasOwnProperty('url')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'url');
            } else if (!value.hasOwnProperty('img')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'img');
            } else if (!value.hasOwnProperty('originalPrice')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'originalPrice');
            } else if (!value.hasOwnProperty('price')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'price');
            } else if (!value.hasOwnProperty('name')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'name');
            } else if (!value.hasOwnProperty('id')) {
                qaTestMode.errorLog('Eksik Storage Değeri', 'id');
            }

            // price, originalPrice'dan büyük mü
            if (value['price'] > value['originalPrice'] && !value['notConvertedPrice']) {
                qaTestMode.errorLog('Storage price > originalPrice', value['price'] + ' > ' + value['originalPrice']);
            }

            // exchange attribute'u gerekli mi, var mı
            if (value['notConvertedPrice'] && !value['exchange']) {
                qaTestMode.errorLog('Storage Exchange hatası', 'exchange: attribute\'u eksik!');
            }
        });
    },
    parseJSON: function (text) { // JSON'lar düzgün mü diye kontrol edip, düzgünse parse eder, yoksa hata bastırır
        var parsedVariable;

        try {
            parsedVariable = JSON.parse(text) || [];
        } catch (e) {
            parsedVariable = [];
            window.qaTestMode.errorLog('Invalid JSON trying to be written to storage', text);
            window.qaTestMode.errorLog('JSON could not be parsed for DumpStorage!', e);
        }

        return parsedVariable;
    },
    _vairoDumpStorage: function (initialized) { // İçi true ise storage dinleyicisini aktive eder, false ise storage bastırır
        var InsiderStorageFunction = ((window.Insider || {}).storage || {}).localStorage || {};
        var originalLocalStorageSet = window.localStorage.setItem;

        if (!window.vTestStorageOverridden) {
            Object.defineProperty(InsiderStorageFunction, 'ins-cart-product-list', {
                get() {
                    return InsiderStorageFunction.get('ins-cart-product-list');
                },
                set(newValue) {
                    window.console.log('%cStorage Updated !', 'font-size:20px;color:red');
                    var sData = (qaTestMode.parseJSON(newValue) || []).data || [];
                    var insStorage = typeof sData === 'object' ? sData :
                        qaTestMode.parseJSON(sData);

                    InsiderStorageFunction.set({
                        name: 'ins-cart-product-list',
                        value: newValue
                    });

                    if (qaTestMode.systemRule.isOnCartPage() === false) {
                        InsiderStorageFunction.set({
                            name: 'vTest-last-product-list',
                            value: JSON.stringify(insStorage.productList)
                        });
                    }
                    qaTestMode.testStorage(insStorage);
                }
            });

            Object.defineProperty(InsiderStorageFunction, 'ins-wishlist-product-list', {
                get() {
                    return InsiderStorageFunction.get('ins-wishlist-product-list');
                },
                set(newValue) {
                    window.console.log('%cWishlist Storage Updated !', 'font-size:20px;color:red');
                    var sData = (qaTestMode.parseJSON(newValue) || []).data || [];
                    var insStorage = typeof sData === 'object' ? sData :
                        qaTestMode.parseJSON(sData);

                    InsiderStorageFunction.set({
                        name: 'ins-wishlist-product-list',
                        value: newValue
                    });

                    if (qaTestMode.systemRule.isOnWishlistPage() === false) {
                        InsiderStorageFunction.set({
                            name: 'vTest-last-wishlist-product-list',
                            value: JSON.stringify(insStorage.productList)
                        });
                    }

                    qaTestMode.testStorage(insStorage);
                }
            });

            window.vTestStorageOverridden = true;
        }

        window.localStorage.setItem = function (storageName, storeValue, isDuplicate) {
            originalLocalStorageSet.apply(this, arguments);

            if (!isDuplicate) {
                if (storageName === 'ins-cart-product-list') {

                    window.console.log('%cStorage Updated !', 'font-size:20px;color:red');
                    var sData = (qaTestMode.parseJSON(localStorage.getItem('ins-cart-product-list')) || []).data ||
                        qaTestMode.parseJSON(localStorage['ins-cart-product-list']).data || [];
                    var insStorage = typeof sData === 'object' ? sData :
                        qaTestMode.parseJSON(sData);

                    if (qaTestMode.systemRule.isOnCartPage() === false) {
                        window.localStorage['vTest-last-product-list'] = JSON.stringify(insStorage.productList);
                    }

                    qaTestMode.testStorage(insStorage);
                }

                if (storageName === 'ins-wishlist-product-list') {

                    window.console.log('%cWishlist Storage Updated !', 'font-size:20px;color:red');
                    var wishlistData = (qaTestMode.parseJSON(localStorage.getItem('ins-wishlist-product-list')) || [])
                        .data || qaTestMode.parseJSON(localStorage['ins-wishlist-product-list']).data || [];
                    var insWisStorage = typeof wishlistData === 'object' ? wishlistData :
                        qaTestMode.parseJSON(wishlistData);

                    if (qaTestMode.systemRule.isOnCartPage() === false) {
                        window.localStorage['vTest-last-wishlist-product-list'] =
                            JSON.stringify(insWisStorage.productList);
                    }

                    qaTestMode.testStorage(insWisStorage);
                }

                if (storageName === 'prodCats') {
                    window.console.log('%cspAddToCart Click Listener Çalıştı!', 'font-size:20px;color:red');
                }
            }
        };

        initialized ? this.log('Storage Listener', 'Initialized') : '';
    },
    offlineMode: function () { // hitSend'in kapalı olduğu durumlar için eski tip offline kontrol bastırır
        // !!!!!! Bu offlineMode eski tamperMonkey'in bire-bir aynısı. Üzerinden diğer kodlar örnek alınarak geçilmeli!!
        // TODO
        // Window'lar atılıp, modül yapısına çevrilecek
        // Üzerinden tekrar geçilip, refactor edilerek detaylıca tekrar test edilmeli

        //********************************************************************************************** */
        //---------------------------------------- SWITCHES -----------------------------------------------
        //********************************************************************************************** */

        var testSwitch = function (flag) {
            if (flag === true) {
                localStorage.setItem('vairoExtensionTest', true);
                window.console.log('%cTest Logging is Enabled!', 'color:blue');
            } else if (flag === false) {
                localStorage.setItem('vairoExtensionTest', false);
                window.console.log('%cTest Logging is Disabled!', 'color:red');
            }

            return window.localStorage['vairoExtensionTest'] === 'true';
        };

        this.vairoDebugSwitch = function () {
            this.localStorage.setItem('vapi_debug', this.localStorage.getItem('vapi_debug') !== 'true');
        };

        var debugPrint = function () {
            if (this.localStorage.getItem('vapi_debug') === 'true') {
                window.console.log('------------DEBUG LOG------------');
                window.console.log(arguments);
            }
        };

        // *************************************************************************************************
        // ------------------------------------------ RULE PRINTS ------------------------------------------
        // *************************************************************************************************

        // getCurrentProduct
        this.getCurrentProduct = function () {
            this.printGetCurrentProduct(qaTestMode.systemRule.getCurrentProduct(), 'getCurrentProduct');
            // if (typeof spApi.getCurrentProduct_Mobile !== 'undefined') {
            //     this.printGetCurrentProduct(spApi.getCurrentProduct_Mobile(), 'getCurrentProduct_Mobile');
            // }
        };

        this.printGetCurrentProduct = function (dict, methodName) {
            window.console.groupCollapsed('%c' + '# ' + methodName + '()', 'color:gray');
            var keyArray = Object.keys(dict);

            for (var i = 0; i < keyArray.length; i++) {
                window.console.log('%c' + keyArray[i] + ': ' + '%c' + dict[keyArray[i]],
                    'color:brown; font-weight:bold', '');

                if (keyArray[i] === 'url') {
                    window.console.log('  ', this.location === dict[keyArray[i]]);
                }

                if (keyArray[i] === 'cats') {
                    var arr = dict[keyArray[i]];

                    if (arr instanceof Array) {
                        for (var j = 0; j < arr.length; j++)
                            window.console.log('	' + arr[j]);
                    }
                }
            }
            window.console.groupEnd();
            window.console.log('\n');
        };

        // getPaidProducts
        this.getPaidProducts = function () {
            this.printGetPaidProducts(qaTestMode.systemRule.getPaidProducts(), 'getPaidProducts');
            // if (typeof spApi.getPaidProducts_Mobile !== 'undefined') {
            //     this.printGetPaidProducts(spApi.getPaidProducts_Mobile(), 'getPaidProducts_Mobile');
            // }
        };

        this.printGetPaidProducts = function (arr, methodName) {
            window.console.groupCollapsed('%c' + '# ' + methodName + '()', 'color:gray');
            for (var i = 0; i < arr.length; i++) {
                window.console.group('%c' + 'Item ' + (i + 1), 'color:gray');
                var dict = arr[i] || [];
                var arrayKeys = Object.keys(dict);

                for (var j = 0; j < arrayKeys.length; j++) {
                    window.console.log('	' + '%c' + arrayKeys[j] + ': %c' + dict[arrayKeys[j]],
                        'color:brown; font-weight:bold', '');
                }

                if (typeof dict.img !== 'undefined' && dict.img !== '') {
                    window.console.log('%c   ', 'font-size: 50px; background: url(' + dict.img +
                        ') no-repeat center center; height: 100px; background-size: contain;');
                }
                window.console.groupEnd();

                if (i < arr.length - 1) {
                    window.console.log('\n');
                }
            }

            window.console.groupEnd();
            window.console.log('\n');
        };

        // getCategories
        this.getCategories = function () {
            this.printGetCategories(qaTestMode.systemRule.getCategories(), 'getCategories');
            //
            // if(typeof spApi.getCategories_Mobile !== 'undefined'){
            //     this.printGetCategories(spApi.getCategories_Mobile(),'getCategories_Mobile');
            // }
        };

        this.printGetCategories = function (categoryArray, methodName) {
            window.console.log('%c  ' + methodName + '(): ' + '%c     ' + categoryArray,
                'color:brown; font-weight:bold;', 'font-weight:bold;');

            if (categoryArray instanceof Array) {
                for (var i = 0; i < categoryArray.length; i++)
                    window.console.log('				', categoryArray[i]);
            }
        };

        // getProductCategories
        this.getProductCategories = function () {
            this.printGetProductCategories(qaTestMode.systemRule.getProductCategories(), 'getProductCategories');
        };

        this.printGetProductCategories = function (catArray, methodName) {
            window.console.groupCollapsed('%c' + '# ' + methodName + '()', 'color:gray');

            window.console.log('%c  ' + methodName + '(): ' + '%c     ' + catArray, 'color:brown; font-weight:bold;',
                'font-weight:bold;');

            if (catArray instanceof Array) {
                for (var i = 0; i < catArray.length; i++)
                    window.console.log('				', catArray[i]);
            }
            window.console.groupEnd();
            window.console.log('\n');
        };

        // useCouponButton
        this.useCouponButton = function () {
            window.console.groupCollapsed('%c' + '# useCouponButton()', 'color:gray');
            var dict = qaTestMode.systemRule.useCouponButton();
            var ArrayOfKeys = Object.keys(dict);

            window.console.log('%c  useCouponButton():', 'color:brown; font-weight:bold;');

            for (var i = 0; i < ArrayOfKeys.length; i++) {
                window.console.log('	' + '%c' + ArrayOfKeys[i] + ': %c' + dict[ArrayOfKeys[i]],
                    'color:brown; font-weight:bold', '');

                var str = '';

                if (ArrayOfKeys[i] === 'button') {
                    str = '%csQuery("' + dict[ArrayOfKeys[i]] + '")';

                    window.console.log('		%cQuery: ' + str, 'color:chocolate; font-weight:bold', '');
                }

                if (ArrayOfKeys[i] === 'couponInput') {
                    str = 'sQuery("' + dict[ArrayOfKeys[i]] + '")';

                    window.console.log('		%cQuery: ' + '%c' + str, 'color:chocolate; font-weight:bold', '');
                }
            }
            window.console.groupEnd();
            window.console.log('\n');
        };

        // checkLogs
        this.checkLogs = function () { // TODO hitParser içerisinde bu fonksiyon eksik. Yeni API'a da uygun yazılmalı
            if (typeof spApi !== 'undefined' && typeof spApi.errLogs !== 'undefined') {
                window.console.log('%c  errLogs:              ' + '%c' + spApi.errLogs,
                    'color:brown; font-weight:bold;',
                    'color:red; font-weight: bold;');
            } else {
                window.console.log('%c  errLogs:              ' + '%c' + spApi.errLogs,
                    'color:brown; font-weight:bold;',
                    'font-weight: bold;');
            }
        };

        // userLogin
        this.userLogin = function () {
            if (qaTestMode.systemRule.isUserLoggedIn()) {
                window.console.log('%c  isUserLoggedIn():     ' + '%c' + qaTestMode.systemRule.isUserLoggedIn(),
                    'color:brown; font-weight:bold;', 'color:#27CA00; font-weight: bold;');
            } else {
                window.console.log('%c  isUserLoggedIn():     ' + '%c' + qaTestMode.systemRule.isUserLoggedIn(),
                    'color:brown; font-weight:bold;', 'font-weight: bold;');
            }
        };

        // getLang
        this.getLang = function () {
            window.console.log('%c  getLang():            ' + '%c' + qaTestMode.systemRule.getLang(),
                'color:brown; font-weight:bold;', 'font-weight: bold;');
        };

        // getLang
        this.getLocale = function () {
            if (typeof qaTestMode.systemRule.getLocale !== 'undefined') {
                window.console.log('%c  getLocale():          ' + '%c' + qaTestMode.systemRule.getLocale(),
                    'color:brown; font-weight:bold;', 'font-weight: bold;');
            }
        };

        // getCurrency
        this.getCurrency = function () {
            window.console.log('%c  getCurrency():        ' + '%c' + qaTestMode.systemRule.getCurrency(),
                'color:brown; font-weight:bold;',
                'font-weight:bold;');
        };

        // getCartCount
        this.getCartCount = function () {
            window.console.log('%c  getCartCount():       ' + '%c' + qaTestMode.systemRule.getCartCount(),
                'color:brown; font-weight:bold;',
                'font-weight:bold;');
        };

        // getTotalCartAmount
        this.getTotalCartAmount = function () {
            window.console.log('%c  getTotalCartAmount(): ' + '%c' + qaTestMode.systemRule.getTotalCartAmount(),
                'color:brown; font-weight:bold;', 'font-weight:bold;');
        };

        // getOrderId
        this.getOrderId = function () {
            window.console.log('%c  getOrderId(): ' + '%c' + qaTestMode.systemRule.getOrderId(),
                'color:brown; font-weight:bold;', 'color:green; font-weight:bold');
        };

        // ins-cart-product-list
        this.insCartProductList = function () {
            var insCartInfo = Insider.storage.localStorage.get('ins-cart-product-list'); // TODO pure-js'e çevrilmeli
            var indexFind = insCartInfo.indexOf('totalQuantity');
            var indexStart = indexFind + ('totalQuantity').length + 2;
            var indexEnd = indexStart + 1;
            var quantity = insCartInfo.substring(indexStart, indexEnd);

            window.console.log('%c  ins-cart-product-list: ' + '%c' + quantity, 'color:brown; font-weight:bold;',
                'font-weight:bold');
            window.console.log('		%cSayfa yenilenmezse ins-cart-product-list degeri yenilenmez!', 'color:red');
        };

        // ins-wishlist-product-list
        this.insWishlistProductList = function () {
            var insCartInfo = Insider.storage.localStorage.get('ins-wishlist-product-list'); // TODO pure-js'e çevrilmeli
            var indexFind = insCartInfo.indexOf('totalQuantity');
            var indexStart = indexFind + ('totalQuantity').length + 2;
            var indexEnd = indexStart + 1;
            var quantity = insCartInfo.substring(indexStart, indexEnd);

            window.console.log('%c  ins-wishlist-product-list: ' + '%c' + quantity, 'color:brown; font-weight:bold;',
                'font-weight:bold');
            window.console.log('		%cSayfa yenilenmezse ins-wishlist-product-list degeri yenilenmez!',
                'color:red');
        };

        window.console.log('%c-- SYSTEM RULES CHECKER START --', 'background: #343434; color: #F6F6F6');
        qaTestMode.page_rules();
        window.console.log('%c-- SYSTEM RULES CHECKER END --', 'background: #343434; color: #F6F6F6');

        this.spApi = this.spApi || []; // TODO Böyle bir şeye kesinlikle gerek olmamalı. offline'ın this'leri de sağlıksız

        var originalreInitOnChange = spApi.reInitOnChange;

        if (this.Insider) { // TODO initializeHitAPI işlevsel değil AMA eventManager.on(re-initialize) çok iyi çalışıyor
            originalreInitOnChange = this.Insider.initialize;
            debugPrint('Insider.initializeHitAPI: OverWritten', (this.Insider || []).initializeHitAPI);
            this.Insider.eventManager.on('init-manager:re-initialize', function () {
                window.console.log('%cSpApi Reinited!', 'font-size:26px;color:red;font-weight:bold');
                window.console.log('%cPage Info :', 'font-size:20px;font-weight:bold');
                window.isOnPage(false);
                window.console.log('%cPage Rules :', 'font-size:20px;font-weight:bold');
                qaTestMode.page_rules();
            });
        }

        /** Reinit function name must be 'reinit' **/
        spApi.reInitOnChange = function () { // TODO Bu sağlıksız bir dinleme. Yeni API'a uygun da değil
            // TODO Düzgünü hitParser içerisinde var
            originalreInitOnChange.apply(this, arguments);
            window.console.log('%cSpApi Reinited!', 'font-size:26px;color:red;font-weight:bold');
            window.console.log('%cPage Info :', 'font-size:20px;font-weight:bold');
            window.isOnPage(false);
            window.console.log('%cPage Rules :', 'font-size:20px;font-weight:bold');
            qaTestMode.page_rules();
        };

        if (typeof spApi.reinit !== 'undefined') { // TODO bunların işlevini bilmiyoruz
            spApi.reinit();
        }

        if (typeof spApi.freejs !== 'undefined') { // TODO bunların işlevini bilmiyoruz
            spApi.freejs();
        }

        var hitTrack = function () {
            spApi.hitTrackOpen = function () { // TODO bu sağlıklı bir kontrol değil ve spApi'ye bağımlı(this olmalı)
                spApi.hitTrack = true;
            };
            spApi.hitTrackClose = function () { // TODO bu sağlıklı bir kontrol değil ve spApi'ye bağımlı(this olmalı)
                spApi.hitTrack = false;
            };

            var prefilter = sQuery.ajaxPrefilter || false;

            if (prefilter && spApi.hitSend === false) {
                prefilter(function (request) {
                    if (spApi.hitTrack === true || this.hitTrack === true) { // TODO bu sağlıklı bir kontrol değil
                        if ((request.url || '').indexOf('hit.api.useinsider.com/hit') !== -1) {
                            window.console.log('%cHit Request', 'font-size:18px;',
                                qaTestMode.parseJSON(request.data || '{}') || {});

                            if (testSwitch()) {
                                window.console.log('%chitSend:   ' + '%c' + spApi.hitSend, 'color:orange',
                                    'font-weight: bold;');
                                setTimeout(function () {
                                    window.console.log('%chitSend:   ' + '%c' + spApi.hitSend, 'color:orange',
                                        'font-weight: bold;');
                                }, 1000);
                            }
                        }
                    }
                });
            } else {
                if (!this.tamperAjaxActive) {
                    var ajaxListener = function (callback) {
                        var originalSendFunction = XMLHttpRequest.prototype.send;

                        XMLHttpRequest.prototype.send = function (data) {
                            this.addEventListener('readystatechange', function () {
                                if (this.responseType !== 'arraybuffer' && this.responseType !== 'blob' &&
                                    this.readyState === 4 && this.status === 200 && typeof callback === 'function') {
                                    try {
                                        callback(this.responseURL, data); // this.responseText is the 3rd argument
                                    } catch (error) {
                                        spApi.conLog('Something is crashed, Event:' + error);
                                    }
                                }
                            });

                            originalSendFunction.apply(this, arguments);
                        };
                    };

                    setTimeout(function () {
                        window.console.log('%chitSend:   ' + '%c' + spApi.hitSend, 'color:orange',
                            'font-weight: bold;');
                    }, 1000);

                    ajaxListener(function (url, request) {
                        if (spApi.hitTrack === true || this.hitTrack === true) {
                            if ((url || '').indexOf('hit.api.useinsider.com/hit') !== -1) {
                                window.console.log('%cHit Request', 'font-size:18px;',
                                    qaTestMode.parseJSON(request || '{}') || {});
                                this.vTest.hitInfo(qaTestMode.parseJSON(request || '{}') || {});
                            }
                        }
                    });
                    this.tamperAjaxActive = true;
                }
            }
        };

        hitTrack(); // TODO bu sağlıklı bir kontrol değil ve spApi'ye bağımlı
        spApi.hitTrackOpen(); // TODO bu sağlıklı bir kontrol değil ve spApi'ye bağımlı

        this.vTest = {};

        testSwitch = function (flag) {
            if (flag === true) {
                localStorage.setItem('vairoExtensionTest', true);
                window.console.log('%cTest Logging is Enabled!', 'color:blue');
            } else if (flag === false) {
                localStorage.setItem('vairoExtensionTest', false);
                window.console.log('%cTest Logging is Disabled!', 'color:red');
            }

            return window.localStorage['vairoExtensionTest'] === 'true';
        };

        this.vairoDebugSwitch = function () {
            this.localStorage.setItem('vapi_debug', this.localStorage.getItem('vapi_debug') !== 'true');
        };

        window.consoleLogFix = function () { // Daha sağlıklı yapılabilir.
            sQuery('body').append(sQuery('<iframe id="consoleLogFix"></iframe>'));

            sQuery('#consoleLogFix').elementLoadComplete(function () {
                window.console.log = sQuery('#consoleLogFix')[0].contentwindow.console.log;
                window.console.warn = sQuery('#consoleLogFix')[0].contentwindow.console.warn;
                window.console.info = sQuery('#consoleLogFix')[0].contentwindow.console.info;
                window.console.table = sQuery('#consoleLogFix')[0].contentwindow.console.table;
            });

            window.console.warn('Sitede console log ve türevleri devre dışı bırakılmış, ilgili düzeltme uygulandı.');
        };

        //----------------------------------------MAIN--------------------------------------------------

        this.onClickIsOnPage = function (element, timeout) {
            if (typeof element === 'undefined') {
                element = sQuery(document);
            }

            if (typeof timeout === 'undefined') {
                timeout = 500;
            }

            element.on('click', function () {
                setTimeout(function () {
                    window.isOnPage(false);
                }, timeout);
            });
        };
    },
    page_rules: function () {
        //********************************************************************************************** */
        //---------------------------------------- UTILS --------------------------------------------------
        //********************************************************************************************** */

        var testType = function (obj, type) { // isNaN kullanmayın, sağlıklı değil
            // eslint-disable-next-line use-isnan
            return obj.toString() !== 'NaN' && typeof obj !== 'undefined' && typeof obj === type;
        };

        var testPrint = function (name, testedVariable, primaryColor, secondaryColor) {
            if (!localStorage.getItem('disable_vtest')) {
                window.console.log('%c' + name + ':' + '%c ' + testedVariable,
                    (primaryColor || 'color:orange;background-color:black;font-weight:bold;'),
                    (secondaryColor || 'color:red; font-weight: bold;'));
            }
        };

        //********************************************************************************************** */
        //---------------------------------------- V-TESTS-------------------------------------------------
        //********************************************************************************************** */

        this.vTest = {};

        this.vTest.general = function () {
            if (typeof (qaTestMode.systemRule.isOnMainPage() + qaTestMode.systemRule.isOnCategoryPage() +
                    qaTestMode.systemRule.isOnProductPage() + qaTestMode.systemRule.isOnCartPage() +
                    qaTestMode.systemRule.isOnAfterPaymentPage() +
                    qaTestMode.systemRule.isOnRegSuccessPage()) !== 'number') {
                testPrint('isOnPage kuralı hatalı değer!', 'Boolean dönmeyen isOnPage var!');
            } else if ((qaTestMode.systemRule.isOnMainPage() + qaTestMode.systemRule.isOnCategoryPage() +
                    qaTestMode.systemRule.isOnProductPage() + qaTestMode.systemRule.isOnCartPage() +
                    qaTestMode.systemRule.isOnAfterPaymentPage() + qaTestMode.systemRule.isOnRegSuccessPage()) > 1) {
                testPrint('Duplicate isOnPage result', 'Birden fazla true dönen isOnPage var!');
            }
        };

        this.vTest.productFallback = function () {
            var product = qaTestMode.systemRule.getCurrentProduct();

            if (typeof qaTestMode.systemRule.getCurrentProduct() === 'object') {
                testType(product.id, 'string') ? '' :
                    testPrint('Product ID Fallback', typeof product.id);

                testType(product.name, 'string') ? '' :
                    testPrint('Product Name Fallback', typeof product.name);

                testType(product.price, 'number') ? '' :
                    testPrint('Product Price Fallback', typeof product.price);

                product.price > 1e+20 ? testPrint('getCurrentProduct Price Error!', product.price) : '';

                product.price > 1e+20 ?
                    testPrint('getCurrentProduct originalPrice Error!', product.originalPrice) : '';

                testType(product.originalPrice, 'number') ? '' :
                    testPrint('Product originalPrice Fallback', typeof product.originalPrice);

                testType(product.img, 'string') ? '' :
                    testPrint('Product Image Fallback', typeof product.img);

                testType(product.url, 'string') ? '' :
                    testPrint('Product URL Fallback', typeof product.url);

                testType(product.cats, 'object') && product.cats.length !== 'undefined' ? '' :
                    testPrint('Product Categories Fallback', typeof product.cats);
            } else {
                testPrint('spApi.getCurrentProduct does not return an Object!!', spApi.getCurrentProduct());
            }
        };

        this.vTest.hitInfo = function (hitObject) { // TODO
            testPrint('HIT page_type', hitObject.page_type, 'color:blue;', 'font-weight: bold;');
        };

        this.vTest['categories'] = function (categories) {
            if (typeof categories === 'object' && typeof categories.length === 'number') {
                categories.map(function (category) {
                    if (typeof category !== 'string') {
                        testPrint('Category type should be string: ', category);
                    } else {
                        category.split(' ').map(function (word) {
                            if (word.charAt(0) !== word.toUpperCase().charAt(0)) {
                                testPrint('First Letter Should Be Upper Case For Categories: ', word, category);
                            }

                            if (word.slice(1) !== word.slice(1).toLowerCase()) {
                                testPrint('Only the First Letter Should Be Upper Case For Categories: ',
                                    word, category);
                            }
                        });
                    }
                });
            } else {
                testPrint('Category function returns wrong object type: ', categories);
            }
        };

        this.vTest.couponButton = function () {
            try {
                document.querySelectorAll(qaTestMode.systemRule.useCouponButton().button).length > 0 ? '' :
                    testPrint('CouponButton Does Not Exists: ', qaTestMode.systemRule.useCouponButton().button);
                document.querySelectorAll(qaTestMode.systemRule.useCouponButton().couponInput).length > 0 ? '' :
                    testPrint('CouponButton Does Not Exists: ', qaTestMode.systemRule.useCouponButton().couponInput);
            } catch (e) {
                qaTestMode.errorLog('Coupon Button Error!', e);
            }
        };

        // Main Page
        if (qaTestMode.systemRule.isOnMainPage()) {
            window.console.log('%c-------MainPageControls-------', 'color:red; font-weight:bold;');
            window.isOnPage();

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();

            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
            this.vTest.productFallback();
        }

        // Category Page
        else if (qaTestMode.systemRule.isOnCategoryPage()) {
            window.console.log('%c-----CategoryPageControls-----', 'color:red; font-weight:bold;');
            window.isOnPage();
            this.getCategories();

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();

            this.vTest.categories(qaTestMode.systemRule.getCategories());
            this.vTest.productFallback();

            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
        }

        // Product Page
        else if (qaTestMode.systemRule.isOnProductPage()) {
            window.console.log('%c-----ProductPageControls------', 'color:red; font-weight:bold;');
            window.isOnPage();
            this.getCurrentProduct();

            window.localStorage['vairo-last-payload'] = JSON.parse(window._vairoGetPayload());
            window.localStorage['vairo-last-id'] = qaTestMode.systemRule.getCurrentProduct().id;
            /* if (typeof spApi.getVersusProductDetail !== 'undefined') {
                this.getVersusProductDetail();
            } */
            this.getProductCategories();
            window.console.groupEnd();

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();
            this.vTest.categories(qaTestMode.systemRule.getProductCategories());
            this.vTest.productFallback();
            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
        }

        // Cart Page
        else if (qaTestMode.systemRule.isOnCartPage()) {
            window.console.log('%c-------CartPageControls-------', 'color:red; font-weight:bold;');
            window.isOnPage();
            this.getPaidProducts();

            if (qaTestMode.systemRule.isOnCouponPage()) {
                this.useCouponButton();
                //this.isCouponCodeApplied();
                this.vTest.couponButton();
            }
            this.getTotalCartAmount();
            window.console.log('\n');

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();
            try {
                this.c();
            } catch (e) {
                window.console.log('Error: ', e);
            }
            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
        }

        // Wishlist Page
        else if (qaTestMode.systemRule.isOnWishlistPage()) {
            window.console.log('%c-------CartPageControls-------', 'color:red; font-weight:bold;');
            window.isOnPage();
            this.getWishlistProducts();

            this.getTotalCartAmount();
            window.console.log('\n');

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();
            try {
                this.insWishlistProductList();
            } catch (e) {
                window.console.log('Error: ', e);
            }
            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
        }

        // Coupon Page
        else if (qaTestMode.systemRule.isOnCouponPage()) {
            if (!qaTestMode.systemRule.isOnCartPage()) {
                window.isOnPage();
                this.useCouponButton();
                //this.isCouponCodeApplied();
                this.vTest.couponButton();
            }
            window.console.log('%c------------------------------', 'color:red; font-weight:bold;');
        }

        // AfterPayment Page
        else if (qaTestMode.systemRule.isOnAfterPaymentPage()) {
            window.isOnPage();
            this.getOrderId();
            window.console.log('\n');

            this.userLogin();
            this.getLang();
            this.getLocale();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();
        }

        // RegSuccess Page
        else if (qaTestMode.systemRule.isOnRegSuccessPage()) {
            window.isOnPage();
            window.console.log('\n');

            this.userLogin();
            this.getLang();
            this.getCurrency();
            this.checkLogs();
            this.getCartCount();
            this.vTest.productFallback();
        } else {
            window.console.log('%cTrue donen isOnPage() sorgusu yok', 'color:red');
            this.vTest.productFallback();
        }

        this.vTest.general();
        window.console.log('\n\n');
    }
};

qaTestMode.init();
Leave a Comment