/*
 * Copyright (C) 2013 salesforce.com, inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.auraframework.impl.coql;

import org.auraframework.controller.java.ServletConfigController;
import org.auraframework.system.AuraContext.Mode;
import org.auraframework.test.WebDriverTestCase;
import org.auraframework.test.annotation.ThreadHostileTest;
import org.openqa.selenium.By;

/**
 * Automation for COQL (Component Query Language). COQL is available in all modes except PRODUCTION
 */
public class ComponentQueryLanguageUITest extends WebDriverTestCase {
    public ComponentQueryLanguageUITest(String name) {
        super(name);
    }

    /**
     * Verify that query language is not available in PROD mode.
     */
    @ThreadHostileTest("PRODUCTION")
    public void testQueryLanguageNotAvailableInprodMode() throws Exception {
        ServletConfigController.setProductionConfig(true);
        open("/test/laxSecurity.app", Mode.PROD);
        Object query = auraUITestingUtil.getEval("return window.$A.getQueryStatement");
        assertNull("Query language should not be available in PROD mode.", query);
    }

    /**
     * Verify that query language is available in non prod mode. For the rest of the test cases, look at
     * js://cmpQueryLanguage.query
     */
    public void testQueryLanguageAvailableInNonprodMode() throws Exception {
        open("/test/laxSecurity.app");
        Boolean query = auraUITestingUtil.getBooleanEval("return $A.hasOwnProperty('getQueryStatement');");
        assertTrue("Query language should be available in non-PROD mode.", query);
        query = auraUITestingUtil.getBooleanEval("return 'query' in $A.getQueryStatement();");
        assertTrue("$A.getQueryStatement() should have 'query' property.", query);
    }

    /**
     * Verify we can use COQL to view rerendering data. This must be a WebDriver test because the rerendering query is
     * only available in STATS mode.
     */
    public void testRerenderingsQuery() throws Exception {
        String rowQuery = "return $A.getQueryStatement().from('rerenderings').query().rowCount;";
        open("/attributesTest/simpleValue.cmp", Mode.STATS);

        Long rowCount = (Long) auraUITestingUtil.getEval(rowQuery);
        assertEquals("Rerenders query should be empty on load.", 0, rowCount.intValue());

        findDomElement(By.cssSelector(".uiButton")).click();
        rowCount = (Long) auraUITestingUtil.getEval(rowQuery);
        assertEquals("Expecting one rerender query entry after attribute value change.", 1, rowCount.intValue());
        String descr = (String) auraUITestingUtil
                .getEval("return $A.getQueryStatement().from('rerenderings').query().rows[0].components['1:2.a'].descr;");
        assertEquals("Unexpected component was rerendered.", "markup://attributesTest:simpleValue", descr);
        String whyName = (String) auraUITestingUtil
                .getEval("return $A.getQueryStatement().from('rerenderings').query().rows[0].components['1:2.a'].why[0].name;");
        assertEquals("Unexpected cause for rerender.", "intAttribute", whyName);

        findDomElement(By.cssSelector(".uiButton")).click();
        rowCount = (Long) auraUITestingUtil.getEval(rowQuery);
        assertEquals("Expecting two rerender query entries after second value change.", 2, rowCount.intValue());
    }
}

@@ -898,16 +898,111 @@
 nium.By;
+%0Aimport org.openqa.selenium.WebDriver;%0Aimport org.openqa.selenium.support.ui.ExpectedCondition;
 %0A%0A/**%0A *
@@ -2621,24 +2621,30 @@
 n %7B%0A        
+final 
 String rowQu
@@ -3015,84 +3015,291 @@
     
-rowCount = (Long) auraUITestingUtil.getEval(rowQuery);%0A        assertEquals(
+auraUITestingUtil.waitUntil(new ExpectedCondition%3CBoolean%3E() %7B%0A            @Override%0A            public Boolean apply(WebDriver d) %7B%0A                Long rowCount = (Long) auraUITestingUtil.getEval(rowQuery);%0A                return rowCount.intValue() == 1;%0A            %7D%0A        %7D, 
 %22Exp
@@ -3364,35 +3364,12 @@
 ge.%22
-, 1, rowCount.intValue()
 );%0A
+%0A
     
@@ -3981,84 +3981,291 @@
     
-rowCount = (Long) auraUITestingUtil.getEval(rowQuery);%0A        assertEquals(
+auraUITestingUtil.waitUntil(new ExpectedCondition%3CBoolean%3E() %7B%0A            @Override%0A            public Boolean apply(WebDriver d) %7B%0A                Long rowCount = (Long) auraUITestingUtil.getEval(rowQuery);%0A                return rowCount.intValue() == 2;%0A            %7D%0A        %7D, 
 %22Exp
@@ -4298,24 +4298,25 @@
 entr
-ies
+y
  after 
-second
+attribute
  val
@@ -4330,32 +4330,8 @@
 ge.%22
-, 2, rowCount.intValue()
 );%0A 

Add waits to fix WebDriver test