<?xml version="1.0" encoding="utf-8"?>
<!--

  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You 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.

-->
<UnitTester testDir="components/ColorPicker/integration/"  xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" testSWF="ColorPicker_integration.mxml">
	<!-- this set of lines form a template that must be in each unit test -->
	<mx:Script>
	<![CDATA[
	
	public static function init(o:DisplayObject):void
	{
	}					
	]]>
	</mx:Script>
	<mx:Metadata>
	<![CDATA[
		[Mixin]
	]]>
	</mx:Metadata>	
	<!-- end of set of lines that must be in each unit test -->
	<mx:Script>
	<![CDATA[
	import mx.controls.Image;
	import mx.styles.StyleManager;
	import mx.managers.SystemManager;
	public function scriptFunction(a:String, b:int):String
	{
		return a + ":" + b.toString();
	}
	public var styleDecl:Object;
	public var styleObj:Object;

	]]>
	</mx:Script>
	<testCases>

		<TestCase testID="202458_The_value_in_the_textinput_is_actually_referring_to_the_last_mouseover_color_value" keywords="[ColorPicker, integration, selectedColor, keyboard]" description="Checking whether the selectedColor gets applied to the backgroundColor of a TextInput using bitmap comparision">
			<setup>
				<ResetComponent target="myColorPicker" className="mx.controls::ColorPicker" waitEvent="updateComplete" />				
			</setup>
			<body>
				<RunCode code="application.myColorPicker.open()" waitEvent="open" waitTarget="myColorPicker"/>
				<WaitForEffectsToEnd />
                <SetProperty target="myColorPicker" propertyName="selectedColor" value="0xff0000" />
				<RunCode code="application.myColorPicker.close()" waitEvent="close" waitTarget="myColorPicker"/>
				<WaitForEffectsToEnd />
				<RunCode code="application.myColorPicker.open()" waitEvent="open" waitTarget="myColorPicker"/>
				<WaitForEffectsToEnd />
				<DispatchMouseEvent target="myColorPicker.mx_internal:dropdown" type="mouseMove" localX="10" localY="100" waitEvent="itemRollOver" waitTarget="myColorPicker"/>
				<DispatchMouseEvent target="myColorPicker" type="mouseMove" localX="1" localY="100" waitEvent="itemRollOut" waitTarget="myColorPicker"/>
				<DispatchMouseClickEvent target="myColorPicker" stageX="10" stageY="10" waitEvent="close" waitTarget="myColorPicker"/>
				<DispatchMouseClickEvent target="myColorPicker" localX="10" localY="10" waitEvent="open" waitTarget="myColorPicker"/>
				<WaitForEffectsToEnd />
				<CompareBitmap url="../integration/baselines/$testID.png" target="myColorPicker.mx_internal:dropdown" />
			</body>
		</TestCase>

		
	</testCases>
</UnitTester>
