Best Python code snippet using pyatom_python
table.py
Source:table.py  
...96                    continue97                if re.match(row_text, cell.AXValue):98                    selected = True99                    if not parent_cell.AXSelected:100                        x, y, width, height = self._getobjectsize(parent_cell)101                        window.clickMouseButtonLeftWithMods((x + width / 2,102                                                             y + height / 2),103                                                            ['<command_l>'])104                        # Following selection doesn't work105                        # parent_cell.AXSelected=True106                        self.wait(0.5)107                    else:108                        # Selected109                        pass110                    break111            if not selected:112                raise LdtpServerException(u"Unable to select row: %s" % row_text)113        if not selected:114            raise LdtpServerException(u"Unable to select any row")115        return 1116    def multiremove(self, window_name, object_name, row_text_list, partial_match = False):117        """118        Remove multiple row119        @param window_name: Window name to type in, either full name,120        LDTP's name convention, or a Unix glob.121        @type window_name: string122        @param object_name: Object name to type in, either full name,123        LDTP's name convention, or a Unix glob. 124        @type object_name: string125        @param row_text_list: Row list with matching text to select126        @type row_text: string127        @return: 1 on success.128        @rtype: integer129        """130        object_handle=self._get_object_handle(window_name, object_name)131        if not object_handle.AXEnabled:132            raise LdtpServerException(u"Object %s state disabled" % object_name)133        object_handle.activate()134        unselected = False135        try:136            window=self._get_front_most_window()137        except (IndexError, ):138            window=self._get_any_window()139        for row_text in row_text_list:140            selected = False141            for cell in object_handle.AXRows:142                parent_cell = cell143                cell = self._getfirstmatchingchild(cell, "(AXTextField|AXStaticText)")144                if not cell:145                    continue146                if re.match(row_text, cell.AXValue):147                    unselected = True148                    if parent_cell.AXSelected:149                        x, y, width, height = self._getobjectsize(parent_cell)150                        window.clickMouseButtonLeftWithMods((x + width / 2,151                                                             y + height / 2),152                                                            ['<command_l>'])153                        # Following selection doesn't work154                        # parent_cell.AXSelected=False155                        self.wait(0.5)156                    else:157                        # Unselected158                        pass159                    break160            if not unselected:161                raise LdtpServerException(u"Unable to select row: %s" % row_text)162        if not unselected:163            raise LdtpServerException(u"Unable to unselect any row")164        return 1165    def selectrowpartialmatch(self, window_name, object_name, row_text):166        """167        Select row partial match168        @param window_name: Window name to type in, either full name,169        LDTP's name convention, or a Unix glob.170        @type window_name: string171        @param object_name: Object name to type in, either full name,172        LDTP's name convention, or a Unix glob. 173        @type object_name: string174        @param row_text: Row text to select175        @type row_text: string176        @return: 1 on success.177        @rtype: integer178        """179        object_handle=self._get_object_handle(window_name, object_name)180        if not object_handle.AXEnabled:181            raise LdtpServerException(u"Object %s state disabled" % object_name)182        for cell in object_handle.AXRows:183            if re.search(row_text,184                         cell.AXChildren[0].AXValue):185                if not cell.AXSelected:186                    object_handle.activate()187                    cell.AXSelected=True188                else:189                    # Selected190                    pass191                return 1192        raise LdtpServerException(u"Unable to select row: %s" % row_text)193    def selectrowindex(self, window_name, object_name, row_index):194        """195        Select row index196        @param window_name: Window name to type in, either full name,197        LDTP's name convention, or a Unix glob.198        @type window_name: string199        @param object_name: Object name to type in, either full name,200        LDTP's name convention, or a Unix glob. 201        @type object_name: string202        @param row_index: Row index to select203        @type row_index: integer204        @return: 1 on success.205        @rtype: integer206        """207        object_handle=self._get_object_handle(window_name, object_name)208        if not object_handle.AXEnabled:209            raise LdtpServerException(u"Object %s state disabled" % object_name)210        count=len(object_handle.AXRows)211        if row_index < 0 or row_index > count:212            raise LdtpServerException('Row index out of range: %d' % row_index)213        cell=object_handle.AXRows[row_index]214        if not cell.AXSelected:215            object_handle.activate()216            cell.AXSelected=True217        else:218            # Selected219            pass220        return 1221    def selectlastrow(self, window_name, object_name):222        """223        Select last row224        @param window_name: Window name to type in, either full name,225        LDTP's name convention, or a Unix glob.226        @type window_name: string227        @param object_name: Object name to type in, either full name,228        LDTP's name convention, or a Unix glob. 229        @type object_name: string230        @return: 1 on success.231        @rtype: integer232        """233        object_handle=self._get_object_handle(window_name, object_name)234        if not object_handle.AXEnabled:235            raise LdtpServerException(u"Object %s state disabled" % object_name)236        cell=object_handle.AXRows[-1]237        if not cell.AXSelected:238            object_handle.activate()239            cell.AXSelected=True240        else:241            # Selected242            pass243        return 1244    def setcellvalue(self, window_name, object_name, row_index,245                     column=0, data=None):246        """247        Set cell value248        @param window_name: Window name to type in, either full name,249        LDTP's name convention, or a Unix glob.250        @type window_name: string251        @param object_name: Object name to type in, either full name,252        LDTP's name convention, or a Unix glob. 253        @type object_name: string254        @param row_index: Row index to get255        @type row_index: integer256        @param column: Column index to get, default value 0257        @type column: integer258        @param data: data, default value None259                None, used for toggle button260        @type data: string261        @return: 1 on success.262        @rtype: integer263        """264        raise LdtpServerException("Not implemented")265    def getcellvalue(self, window_name, object_name, row_index, column=0):266        """267        Get cell value268        @param window_name: Window name to type in, either full name,269        LDTP's name convention, or a Unix glob.270        @type window_name: string271        @param object_name: Object name to type in, either full name,272        LDTP's name convention, or a Unix glob. 273        @type object_name: string274        @param row_index: Row index to get275        @type row_index: integer276        @param column: Column index to get, default value 0277        @type column: integer278        @return: cell value on success.279        @rtype: string280        """281        object_handle=self._get_object_handle(window_name, object_name)282        if not object_handle.AXEnabled:283            raise LdtpServerException(u"Object %s state disabled" % object_name)284        count=len(object_handle.AXRows)285        if row_index < 0 or row_index > count:286            raise LdtpServerException('Row index out of range: %d' % row_index)287        cell=object_handle.AXRows[row_index]288        count=len(cell.AXChildren)289        if column < 0 or column > count:290            raise LdtpServerException('Column index out of range: %d' % column)291        obj=cell.AXChildren[column]292        if not re.search("AXColumn", obj.AXRole):293            obj=cell.AXChildren[column]294        return obj.AXValue295    def getcellsize(self, window_name, object_name, row_index, column=0):296        """297        Get cell size298        @param window_name: Window name to type in, either full name,299        LDTP's name convention, or a Unix glob.300        @type window_name: string301        @param object_name: Object name to type in, either full name,302        LDTP's name convention, or a Unix glob. 303        @type object_name: string304        @param row_index: Row index to get305        @type row_index: integer306        @param column: Column index to get, default value 0307        @type column: integer308        @return: cell coordinates on success.309        @rtype: list310        """311        object_handle=self._get_object_handle(window_name, object_name)312        if not object_handle.AXEnabled:313            raise LdtpServerException(u"Object %s state disabled" % object_name)314        count=len(object_handle.AXRows)315        if row_index < 0 or row_index > count:316            raise LdtpServerException('Row index out of range: %d' % row_index)317        cell=object_handle.AXRows[row_index]318        count=len(cell.AXChildren)319        if column < 0 or column > count:320            raise LdtpServerException('Column index out of range: %d' % column)321        obj=cell.AXChildren[column]322        if not re.search("AXColumn", obj.AXRole):323            obj=cell.AXChildren[column]324        return self._getobjectsize(obj)325    def rightclick(self, window_name, object_name, row_text):326        """327        Right click on table cell328        @param window_name: Window name to type in, either full name,329        LDTP's name convention, or a Unix glob.330        @type window_name: string331        @param object_name: Object name to type in, either full name,332        LDTP's name convention, or a Unix glob. 333        @type object_name: string334        @param row_text: Row text to right click335        @type row_text: string336        @return: 1 on success.337        @rtype: integer338        """339        object_handle=self._get_object_handle(window_name, object_name)340        if not object_handle.AXEnabled:341            raise LdtpServerException(u"Object %s state disabled" % object_name)342        object_handle.activate()343        self.wait(1)344        for cell in object_handle.AXRows:345            cell = self._getfirstmatchingchild(cell, "(AXTextField|AXStaticText)")346            if not cell:347                continue348            if re.match(row_text, cell.AXValue):349                x, y, width, height = self._getobjectsize(cell)350                # Mouse right click on the object351                cell.clickMouseButtonRight((x + width / 2, y + height / 2))352                return 1353        raise LdtpServerException(u'Unable to right click row: %s' % row_text)354    def checkrow(self, window_name, object_name, row_index, column = 0):355        """356        Check row357        @param window_name: Window name to type in, either full name,358        LDTP's name convention, or a Unix glob.359        @type window_name: string360        @param object_name: Object name to type in, either full name,361        LDTP's name convention, or a Unix glob. 362        @type object_name: string363        @param row_index: Row index to get364        @type row_index: integer365        @param column: Column index to get, default value 0366        @type column: integer367        @return: cell value on success.368        @rtype: string369        """370        raise LdtpServerException("Not implemented")371    def expandtablecell(self, window_name, object_name, row_index, column = 0):372        """373        Expand or contract table cell374        @param window_name: Window name to type in, either full name,375        LDTP's name convention, or a Unix glob.376        @type window_name: string377        @param object_name: Object name to type in, either full name,378        LDTP's name convention, or a Unix glob. 379        @type object_name: string380        @param row_index: Row index to get381        @type row_index: integer382        @param column: Column index to get, default value 0383        @type column: integer384        @return: cell value on success.385        @rtype: string386        """387        raise LdtpServerException("Not implemented")388    def uncheckrow(self, window_name, object_name, row_index, column = 0):389        """390        Check row391        @param window_name: Window name to type in, either full name,392        LDTP's name convention, or a Unix glob.393        @type window_name: string394        @param object_name: Object name to type in, either full name,395        LDTP's name convention, or a Unix glob. 396        @type object_name: string397        @param row_index: Row index to get398        @type row_index: integer399        @param column: Column index to get, default value 0400        @type column: integer401        @return: 1 on success.402        @rtype: integer403        """404        raise LdtpServerException("Not implemented")405    def gettablerowindex(self, window_name, object_name, row_text):406        """407        Get table row index matching given text408        @param window_name: Window name to type in, either full name,409        LDTP's name convention, or a Unix glob.410        @type window_name: string411        @param object_name: Object name to type in, either full name,412        LDTP's name convention, or a Unix glob. 413        @type object_name: string414        @param row_text: Row text to select415        @type row_text: string416        @return: row index matching the text on success.417        @rtype: integer418        """419        object_handle=self._get_object_handle(window_name, object_name)420        if not object_handle.AXEnabled:421            raise LdtpServerException(u"Object %s state disabled" % object_name)422        index=0423        for cell in object_handle.AXRows:424            if re.match(row_text,425                        cell.AXChildren[0].AXValue):426                return index427            index += 1428        raise LdtpServerException(u"Unable to find row: %s" % row_text)429    def singleclickrow(self, window_name, object_name, row_text):430        """431        Single click row matching given text432        @param window_name: Window name to type in, either full name,433        LDTP's name convention, or a Unix glob.434        @type window_name: string435        @param object_name: Object name to type in, either full name,436        LDTP's name convention, or a Unix glob. 437        @type object_name: string438        @param row_text: Row text to select439        @type row_text: string440        @return: row index matching the text on success.441        @rtype: integer442        """443        object_handle=self._get_object_handle(window_name, object_name)444        if not object_handle.AXEnabled:445            raise LdtpServerException(u"Object %s state disabled" % object_name)446        object_handle.activate()447        self.wait(1)448        for cell in object_handle.AXRows:449            cell = self._getfirstmatchingchild(cell, "(AXTextField|AXStaticText)")450            if not cell:451                continue452            if re.match(row_text, cell.AXValue):453                x, y, width, height = self._getobjectsize(cell)454                # Mouse left click on the object455                cell.clickMouseButtonLeft((x + width / 2, y + height / 2))456                return 1457        raise LdtpServerException('Unable to get row text: %s' % row_text)458    def doubleclickrow(self, window_name, object_name, row_text):459        """460        Double click row matching given text461        @param window_name: Window name to type in, either full name,462        LDTP's name convention, or a Unix glob.463        @type window_name: string464        @param object_name: Object name to type in, either full name,465        LDTP's name convention, or a Unix glob. 466        @type object_name: string467        @param row_text: Row text to select468        @type row_text: string469        @return: row index matching the text on success.470        @rtype: integer471        """472        object_handle=self._get_object_handle(window_name, object_name)473        if not object_handle.AXEnabled:474            raise LdtpServerException(u"Object %s state disabled" % object_name)475        object_handle.activate()476        self.wait(1)477        for cell in object_handle.AXRows:478            cell = self._getfirstmatchingchild(cell, "(AXTextField|AXStaticText)")479            if not cell:480                continue481            if re.match(row_text, cell.AXValue):482                x, y, width, height = self._getobjectsize(cell)483                # Mouse double click on the object484                cell.doubleClickMouse((x + width / 2, y + height / 2))485                return 1486        raise LdtpServerException('Unable to get row text: %s' % row_text)487    def doubleclickrowindex(self, window_name, object_name, row_index, col_index=0):488        """489        Double click row matching given text490        @param window_name: Window name to type in, either full name,491        LDTP's name convention, or a Unix glob.492        @type window_name: string493        @param object_name: Object name to type in, either full name,494        LDTP's name convention, or a Unix glob.495        @type object_name: string496        @param row_index: Row index to click497        @type row_index: integer498        @param col_index: Column index to click499        @type col_index: integer500        @return: row index matching the text on success.501        @rtype: integer502        """503        object_handle=self._get_object_handle(window_name, object_name)504        if not object_handle.AXEnabled:505            raise LdtpServerException(u"Object %s state disabled" % object_name)506        count=len(object_handle.AXRows)507        if row_index < 0 or row_index > count:508            raise LdtpServerException('Row index out of range: %d' % row_index)509        cell=object_handle.AXRows[row_index]510        self._grabfocus(cell)511        x, y, width, height = self._getobjectsize(cell)512        # Mouse double click on the object513        cell.doubleClickMouse((x + width / 2, y + height / 2))514        return 1515    def verifytablecell(self, window_name, object_name, row_index,516                        column_index, row_text):517        """518        Verify table cell value with given text519        @param window_name: Window name to type in, either full name,520        LDTP's name convention, or a Unix glob.521        @type window_name: string522        @param object_name: Object name to type in, either full name,523        LDTP's name convention, or a Unix glob. 524        @type object_name: string525        @param row_index: Row index to get...combo_box.py
Source:combo_box.py  
...42            object_handle.Press()43        except AttributeError:44            # AXPress doesn't work with Instruments45            # So did the following work around46            x, y, width, height=self._getobjectsize(object_handle)47            # Mouse left click on the object48            # Note: x + width/2, y + height / 2 doesn't work49            self.generatemouseevent(x + 5, y + 5, "b1c")50            self.wait(5)51            handle=self._get_sub_menu_handle(object_handle, item_name)52            x, y, width, height=self._getobjectsize(handle)53            # on OSX 10.7 default "b1c" doesn't work54            # so using "b1d", verified with Fusion test, this works55            self.generatemouseevent(x + 5, y + 5, "b1d")56            return 157        # Required for menuitem to appear in accessibility list58        self.wait(1)59        menu_list=re.split(";", item_name)60        try:61            menu_handle=self._internal_menu_handler(object_handle, menu_list,62                                                    True)63            # Required for menuitem to appear in accessibility list64            self.wait(1)65            if not menu_handle.AXEnabled:66                raise LdtpServerException(u"Object %s state disabled" % \67                                          menu_list[-1])68            menu_handle.Press()69        except LdtpServerException:70            object_handle.activate()71            object_handle.sendKey(AXKeyCodeConstants.ESCAPE)72            raise73        return 174    # Since selectitem and comboselect implementation are same,75    # for Linux/Windows API compatibility let us assign selectitem to comboselect76    comboselect=selectitem77    def selectindex(self, window_name, object_name, item_index):78        """79        Select combo box item / layered pane based on index80        81        @param window_name: Window name to type in, either full name,82        LDTP's name convention, or a Unix glob.83        @type window_name: string84        @param object_name: Object name to type in, either full name,85        LDTP's name convention, or a Unix glob. 86        @type object_name: string87        @param item_index: Item index to select88        @type object_name: integer89        @return: 1 on success.90        @rtype: integer91        """92        object_handle=self._get_object_handle(window_name, object_name)93        if not object_handle.AXEnabled:94            raise LdtpServerException(u"Object %s state disabled" % object_name)95        self._grabfocus(object_handle.AXWindow)96        try:97            object_handle.Press()98        except AttributeError:99            # AXPress doesn't work with Instruments100            # So did the following work around101            x, y, width, height=self._getobjectsize(object_handle)102            # Mouse left click on the object103            # Note: x + width/2, y + height / 2 doesn't work104            self.generatemouseevent(x + 5, y + 5, "b1c")105        # Required for menuitem to appear in accessibility list106        self.wait(2)107        if not object_handle.AXChildren:108            raise LdtpServerException(u"Unable to find menu")109        # Get AXMenu110        children=object_handle.AXChildren[0]111        if not children:112            raise LdtpServerException(u"Unable to find menu")113        children=children.AXChildren114        tmp_children=[]115        for child in children:116            role, label=self._ldtpize_accessible(child)117            # Don't add empty label118            # Menu separator have empty label's119            if label:120                tmp_children.append(child)121        children=tmp_children122        length=len(children)123        try:124            if item_index < 0 or item_index > length:125                raise LdtpServerException(u"Invalid item index %d" % item_index)126            menu_handle=children[item_index]127            if not menu_handle.AXEnabled:128                raise LdtpServerException(u"Object %s state disabled" % menu_list[-1])129            self._grabfocus(menu_handle)130            x, y, width, height=self._getobjectsize(menu_handle)131            # on OSX 10.7 default "b1c" doesn't work132            # so using "b1d", verified with Fusion test, this works133            window=object_handle.AXWindow134            # For some reason,135            # self.generatemouseevent(x + 5, y + 5, "b1d")136            # doesn't work with Fusion settings137            # Advanced window, so work around with this138            # ldtp.selectindex('*Advanced', 'Automatic', 1)139            """140            Traceback (most recent call last):141               File "build/bdist.macosx-10.8-intel/egg/atomac/ldtpd/utils.py", line 178, in _dispatch142                  return getattr(self, method)(*args)143               File "build/bdist.macosx-10.8-intel/egg/atomac/ldtpd/combo_box.py", line 146, in selectindex144                  self.generatemouseevent(x + 5, y + 5, "b1d")...mouse.py
Source:mouse.py  
...71        object_handle = self._get_object_handle(window_name, object_name)72        if not object_handle.AXEnabled:73            raise LdtpServerException(u"Object %s state disabled" % object_name)74        self._grabfocus(object_handle)75        x, y, width, height = self._getobjectsize(object_handle)76        # Mouse left click on the object77        object_handle.clickMouseButtonLeft((x + width / 2, y + height / 2))78        return 179    def mouserightclick(self, window_name, object_name):80        """81        Mouse right click on an object.82        83        @param window_name: Window name to look for, either full name,84        LDTP's name convention, or a Unix glob.85        @type window_name: string86        @param object_name: Object name to look for, either full name,87        LDTP's name convention, or a Unix glob. Or menu heirarchy88        @type object_name: string89        @return: 1 on success.90        @rtype: integer91        """92        object_handle = self._get_object_handle(window_name, object_name)93        if not object_handle.AXEnabled:94            raise LdtpServerException(u"Object %s state disabled" % object_name)95        self._grabfocus(object_handle)96        x, y, width, height = self._getobjectsize(object_handle)97        # Mouse right click on the object98        object_handle.clickMouseButtonRight((x + width / 2, y + height / 2))99        return 1100    def generatemouseevent(self, x, y, eventType="b1c",101                           drag_button_override='drag_default_button'):102        """103        Generate mouse event on x, y co-ordinates.104        105        @param x: X co-ordinate106        @type x: int107        @param y: Y co-ordinate108        @type y: int109        @param eventType: Mouse click type110        @type eventType: str111        @param drag_button_override: Any drag_xxx value112                Only relevant for movements, i.e. |type| = "abs" or "rel"113                Quartz is not fully compatible with windows, so for drags114                the drag button must be explicitly defined. generatemouseevent115                will remember the last button pressed by default, and drag116                that button, use this argument to override that.117        @type drag_button_override: str118        @return: 1 on success.119        @rtype: integer120        """121        if drag_button_override not in mouse_click_override:122            raise ValueError('Unsupported drag_button_override type: %s' % \123                             drag_button_override)124        global drag_button_remembered125        point = (x, y)126        button = centre  # Only matters for "other" buttons127        click_type = None128        if eventType == "abs" or eventType == "rel":129            if drag_button_override is not 'drag_default_button':130                events = [mouse_click_override[drag_button_override]]131            elif drag_button_remembered:132                events = [drag_button_remembered]133            else:134                events = [move]135            if eventType == "rel":136                point = CGEventGetLocation(CGEventCreate(None))137                point.x += x138                point.y += y139        elif eventType == "b1p":140            events = [press_left]141            drag_button_remembered = drag_left142        elif eventType == "b1r":143            events = [release_left]144            drag_button_remembered = None145        elif eventType == "b1c":146            events = [press_left, release_left]147        elif eventType == "b1d":148            events = [press_left, release_left]149            click_type = double_click150        elif eventType == "b2p":151            events = [press_other]152            drag_button_remembered = drag_other153        elif eventType == "b2r":154            events = [release_other]155            drag_button_remembered = None156        elif eventType == "b2c":157            events = [press_other, release_other]158        elif eventType == "b2d":159            events = [press_other, release_other]160            click_type = double_click161        elif eventType == "b3p":162            events = [press_right]163            drag_button_remembered = drag_right164        elif eventType == "b3r":165            events = [release_right]166            drag_button_remembered = None167        elif eventType == "b3c":168            events = [press_right, release_right]169        elif eventType == "b3d":170            events = [press_right, release_right]171            click_type = double_click172        else:173            raise LdtpServerException(u"Mouse event '%s' not implemented" % eventType)174        for event in events:175            CG_event = CGEventCreateMouseEvent(None, event, point, button)176            if click_type:177                CGEventSetIntegerValueField(178                    CG_event, kCGMouseEventClickState, click_type)179            CGEventPost(kCGHIDEventTap, CG_event)180            # Give the event time to happen181            time.sleep(0.01)182        return 1183    def mousemove(self, window_name, object_name):184        """185        Mouse move on an object.186        187        @param window_name: Window name to look for, either full name,188        LDTP's name convention, or a Unix glob.189        @type window_name: string190        @param object_name: Object name to look for, either full name,191        LDTP's name convention, or a Unix glob. Or menu heirarchy192        @type object_name: string193        @return: 1 on success.194        @rtype: integer195        """196        raise LdtpServerException("Not implemented")197    def doubleclick(self, window_name, object_name):198        """199        Double click on the object200        201        @param window_name: Window name to look for, either full name,202        LDTP's name convention, or a Unix glob.203        @type window_name: string204        @param object_name: Object name to look for, either full name,205        LDTP's name convention, or a Unix glob. Or menu heirarchy206        @type object_name: string207        @return: 1 on success.208        @rtype: integer209        """210        object_handle = self._get_object_handle(window_name, object_name)211        if not object_handle.AXEnabled:212            raise LdtpServerException(u"Object %s state disabled" % object_name)213        self._grabfocus(object_handle)214        x, y, width, height = self._getobjectsize(object_handle)215        window=self._get_front_most_window()216        # Mouse double click on the object217        #object_handle.doubleClick()218        window.doubleClickMouse((x + width / 2, y + height / 2))219        return 1220    def simulatemousemove(self, source_x, source_y, dest_x, dest_y, delay = 0.0):221        """222        @param source_x: Source X223        @type source_x: integer224        @param source_y: Source Y225        @type source_y: integer226        @param dest_x: Dest X227        @type dest_x: integer228        @param dest_y: Dest Y...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
