Best Python code snippet using elementium_python
TerminalEmulator.py
Source:TerminalEmulator.py
1# Copyright (c) 2012-2015 Rusty Wagner2#3# This program is free software: you can redistribute it and/or modify4# it under the terms of the GNU General Public License as published by5# the Free Software Foundation, either version 2 of the License, or6# (at your option) any later version.7#8# This program is distributed in the hope that it will be useful,9# but WITHOUT ANY WARRANTY; without even the implied warranty of10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11# GNU General Public License for more details.12#13# You should have received a copy of the GNU General Public License14# along with this program. If not, see <http://www.gnu.org/licenses/>.15import array16import unicodedata17class TerminalEmulator:18 RENDITION_BOLD = 0x00119 RENDITION_DIM = 0x00220 RENDITION_UNDERLINE = 0x00821 RENDITION_INVERSE = 0x04022 RENDITION_HIDDEN = 0x08023 RENDITION_FOREGROUND_256 = 0x10024 RENDITION_BACKGROUND_256 = 0x20025 RENDITION_WRITTEN_CHAR = 0x800 # Only set when character was written normally, used to detect line wrap on copy/paste26 def __init__(self, rows, cols):27 self.rows = rows28 self.cols = cols29 # Initialize screen arrays30 self.screen = []31 self.rendition = []32 self.other_screen = []33 self.other_rendition = []34 self.alt_screen = False35 self.dirty = set()36 self.default_screen_line = array.array('u')37 self.default_rendition_line = array.array('I')38 for i in xrange(0, cols):39 self.default_screen_line.append(u' ')40 self.default_rendition_line.append(0)41 for i in xrange(0, rows):42 self.screen.append(array.array('u', self.default_screen_line))43 self.rendition.append(array.array('I', self.default_rendition_line))44 self.other_screen.append(array.array('u', self.default_screen_line))45 self.other_rendition.append(array.array('I', self.default_rendition_line))46 self.history_screen = []47 self.history_rendition = []48 self.active_rendition = 049 self.cursor_row = 050 self.cursor_col = 051 self.cursor_visible = True52 self.tab_width = 853 self.scroll_top = 054 self.scroll_bottom = self.rows - 155 self.saved_cursor_row = 056 self.saved_cursor_col = 057 self.saved_normal_cursor_row = 058 self.saved_normal_cursor_col = 059 self.saved_alt_cursor_row = 060 self.saved_alt_cursor_col = 061 self.escape_mode = False62 self.window_title_mode = False63 self.ignored_window_title = False64 self.line_draw = False65 self.utf8_buffer = ""66 self.utf8_len = 067 self.unprocessed_input = u""68 self.application_cursor_keys = False69 self.insert_mode = False70 self.update_callback = None71 self.title_callback = None72 self.response_callback = None73 self.special_chars = {74 u'\x07': self.bell,75 u'\x08': self.backspace,76 u'\x09': self.horizontal_tab,77 u'\x0a': self.line_feed,78 u'\x0b': self.line_feed,79 u'\x0c': self.line_feed,80 u'\x0d': self.carriage_return81 }82 self.escape_sequences = {83 u'@': self.insert_chars,84 u'A': self.cursor_up,85 u'B': self.cursor_down,86 u'C': self.cursor_right,87 u'D': self.cursor_left,88 u'E': self.cursor_next_line,89 u'F': self.cursor_prev_line,90 u'G': self.set_cursor_col,91 u'`': self.set_cursor_col,92 u'd': self.set_cursor_row,93 u'H': self.move_cursor,94 u'f': self.move_cursor,95 u'I': self.cursor_right_tab,96 u'J': self.erase_screen,97 u'?J': self.erase_screen,98 u'K': self.erase_line,99 u'?K': self.erase_line,100 u'r': self.scroll_region,101 u'L': self.insert_lines,102 u'P': self.delete_chars,103 u'M': self.delete_lines,104 u'S': self.scroll_up_lines,105 u'T': self.scroll_down_lines,106 u'X': self.erase_chars,107 u'Z': self.cursor_left_tab,108 u'm': self.graphic_rendition,109 u'h': self.set_option,110 u'l': self.clear_option,111 u'?h': self.set_private_option,112 u'?l': self.clear_private_option,113 u'c': self.device_attr,114 u'>c': self.device_secondary_attr,115 u'n': self.device_status,116 u'?n': self.device_status,117 u'!p': self.soft_reset118 }119 self.charset_escapes = [u' ', u'#', u'%', u'(', u')', u'*', u'+']120 self.line_draw_map = {121 u'j': unicode('\xe2\x94\x98', 'utf8'),122 u'k': unicode('\xe2\x94\x90', 'utf8'),123 u'l': unicode('\xe2\x94\x8c', 'utf8'),124 u'm': unicode('\xe2\x94\x94', 'utf8'),125 u'n': unicode('\xe2\x94\xbc', 'utf8'),126 u'q': unicode('\xe2\x94\x80', 'utf8'),127 u't': unicode('\xe2\x94\x9c', 'utf8'),128 u'u': unicode('\xe2\x94\xa4', 'utf8'),129 u'v': unicode('\xe2\x94\xb4', 'utf8'),130 u'w': unicode('\xe2\x94\xac', 'utf8'),131 u'x': unicode('\xe2\x94\x82', 'utf8')132 }133 def invalidate(self):134 for i in xrange(0, self.rows):135 self.dirty.add(i)136 def resize(self, rows, cols):137 if rows > self.rows:138 # Adding rows139 for i in xrange(self.rows, rows):140 self.screen.append(array.array('u', self.default_screen_line))141 self.rendition.append(array.array('I', self.default_rendition_line))142 self.other_screen.append(array.array('u', self.default_screen_line))143 self.other_rendition.append(array.array('I', self.default_rendition_line))144 elif rows < self.rows:145 if self.alt_screen:146 # Alternate screen buffer is active147 normal_cursor_row = self.saved_normal_cursor_row148 if normal_cursor_row < rows:149 # Cursor is at top, remove lines from bottom150 self.other_screen = self.other_screen[:rows]151 self.other_rendition = self.other_rendition[:rows]152 else:153 # Cursor is at bottom, remove lines from top, and place them in the154 # history buffer155 for i in xrange(0, (normal_cursor_row + 1) - rows):156 screen_line = self.other_screen.pop(0)157 rendition_line = self.other_rendition.pop(0)158 self.history_screen.append(screen_line)159 self.history_rendition.append(rendition_line)160 self.other_screen = self.other_screen[:rows]161 self.other_rendition = self.other_rendition[:rows]162 self.screen = self.screen[:rows]163 self.rendition = self.rendition[:rows]164 else:165 # Normal screen buffer is active166 normal_cursor_row = self.cursor_row167 if normal_cursor_row < rows:168 # Cursor is at top, remove lines from bottom169 self.screen = self.screen[:rows]170 self.rendition = self.rendition[:rows]171 else:172 # Cursor is at bottom, remove lines from top, and place them in the173 # history buffer174 for i in xrange(0, (normal_cursor_row + 1) - rows):175 screen_line = self.screen.pop(0)176 rendition_line = self.rendition.pop(0)177 self.history_screen.append(screen_line)178 self.history_rendition.append(rendition_line)179 self.screen = self.screen[:rows]180 self.rendition = self.rendition[:rows]181 self.other_screen = self.other_screen[:rows]182 self.other_rendition = self.other_rendition[:rows]183 if cols > self.cols:184 # Adding columns185 for i in xrange(0, rows):186 for j in xrange(self.cols, cols):187 self.screen[i].append(u' ')188 self.rendition[i].append(0)189 self.other_screen[i].append(u' ')190 self.other_rendition[i].append(0)191 for j in xrange(self.cols, cols):192 self.default_screen_line.append(u' ')193 self.default_rendition_line.append(0)194 elif cols < self.cols:195 # Removing columns196 for i in xrange(0, rows):197 self.screen[i] = self.screen[i][0:cols]198 self.rendition[i] = self.rendition[i][0:cols]199 self.other_screen[i] = self.other_screen[i][0:cols]200 self.other_rendition[i] = self.other_rendition[i][0:cols]201 self.default_screen_line = self.default_screen_line[0:cols]202 self.default_rendition_line = self.default_rendition_line[0:cols]203 self.rows = rows204 self.cols = cols205 self.scroll_top = 0206 self.scroll_bottom = self.rows - 1207 # Ensure cursors are within bounds208 if self.cursor_col > cols:209 self.cursor_col = cols210 if self.cursor_row >= rows:211 self.cursor_row = rows - 1212 if self.saved_cursor_col > cols:213 self.saved_cursor_col = cols214 if self.saved_cursor_row >= rows:215 self.saved_cursor_row = rows - 1216 if self.saved_normal_cursor_col > cols:217 self.saved_normal_cursor_col = cols218 if self.saved_normal_cursor_row >= rows:219 self.saved_normal_cursor_row = rows - 1220 if self.saved_alt_cursor_col > cols:221 self.saved_alt_cursor_col = cols222 if self.saved_alt_cursor_row >= rows:223 self.saved_alt_cursor_row = rows - 1224 self.invalidate()225 if self.update_callback:226 self.update_callback()227 def response(self, data):228 if self.response_callback:229 self.response_callback(data)230 def bell(self):231 # I'm not going to annoy people here232 pass233 def backspace(self):234 if self.cursor_col > 0:235 self.cursor_col -= 1236 def horizontal_tab(self):237 self.cursor_col += self.tab_width - (self.cursor_col % self.tab_width)238 if self.cursor_col > self.cols:239 self.cursor_col = self.cols240 def scroll_up(self):241 top_screen = self.screen.pop(self.scroll_top)242 top_rendition = self.rendition.pop(self.scroll_top)243 # Only update history if windowing isn't being used and the normal screen buffer is active244 if (self.scroll_top == 0) and (self.scroll_bottom == (self.rows - 1)) and (not self.alt_screen):245 self.history_screen.append(top_screen)246 self.history_rendition.append(top_rendition)247 top_screen = array.array('u', self.default_screen_line)248 top_rendition = array.array('I', self.default_rendition_line)249 else:250 top_screen[0:self.cols] = self.default_screen_line251 top_rendition[0:self.cols] = self.default_rendition_line252 if self.active_rendition != 0:253 for i in xrange(0, self.cols):254 top_rendition[i] = self.active_rendition255 self.screen.insert(self.scroll_bottom, top_screen)256 self.rendition.insert(self.scroll_bottom, top_rendition)257 self.invalidate()258 def line_feed(self):259 if self.cursor_row >= self.scroll_bottom:260 self.scroll_up()261 else:262 self.cursor_row += 1263 def reverse_line_feed(self):264 if self.cursor_row <= self.scroll_top:265 self.insert_lines([1])266 else:267 self.cursor_row -= 1268 def newline(self):269 self.line_feed()270 self.cursor_col = 0271 def carriage_return(self):272 self.cursor_col = 0273 def escape(self):274 self.escape_mode = True275 def write_char(self, ch):276 if self.cursor_col >= self.cols:277 self.newline()278 if self.line_draw and (ch in self.line_draw_map):279 ch = self.line_draw_map[ch]280 if self.insert_mode:281 self.insert_chars([1])282 # Write character at cursor location283 self.screen[self.cursor_row][self.cursor_col] = ch284 self.rendition[self.cursor_row][self.cursor_col] = self.active_rendition | TerminalEmulator.RENDITION_WRITTEN_CHAR285 self.dirty.add(self.cursor_row)286 self.cursor_col += 1287 def erase_rect(self, top_row, left_col, bot_row, right_col):288 for row in xrange(top_row, bot_row):289 if row < 0:290 continue291 if row >= self.rows:292 break293 for col in xrange(left_col, right_col):294 if col < 0:295 continue296 if col >= self.cols:297 break298 self.screen[row][col] = u' '299 self.rendition[row][col] = self.active_rendition300 self.dirty.add(row)301 def cursor_up(self, params):302 count = params[0]303 if count == 0:304 count = 1305 self.cursor_row -= count306 if self.cursor_row < 0:307 self.cursor_row = 0308 def cursor_down(self, params):309 count = params[0]310 if count == 0:311 count = 1312 self.cursor_row += count313 if self.cursor_row >= self.rows:314 self.cursor_row = self.rows - 1315 def cursor_right(self, params):316 count = params[0]317 if count == 0:318 count = 1319 self.cursor_col += count320 if self.cursor_col >= self.cols:321 self.cursor_col = self.cols322 def cursor_left(self, params):323 count = params[0]324 if count == 0:325 count = 1326 self.cursor_col -= count327 if self.cursor_col < 0:328 self.cursor_col = 0329 def cursor_next_line(self, params):330 count = params[0]331 if count == 0:332 count = 1333 self.cursor_col = 0334 self.cursor_row += count335 if self.cursor_row >= self.rows:336 self.cursor_row = self.rows - 1337 def cursor_prev_line(self, params):338 count = params[0]339 if count == 0:340 count = 1341 self.cursor_col = 0342 self.cursor_row -= count343 if self.cursor_row < 0:344 self.cursor_row = 0345 def set_cursor_col(self, params):346 self.cursor_col = params[0] - 1347 if self.cursor_col < 0:348 self.cursor_col = 0349 if self.cursor_col > self.cols:350 self.cursor_col = self.cols351 def set_cursor_row(self, params):352 self.cursor_row = params[0] - 1353 if self.cursor_row < 0:354 self.cursor_row = 0355 if self.cursor_row >= self.rows:356 self.cursor_row = self.rows - 1357 def move_cursor(self, params):358 self.cursor_row = params[0] - 1359 if len(params) < 2:360 self.cursor_col = 0361 else:362 self.cursor_col = params[1] - 1363 if self.cursor_col < 0:364 self.cursor_col = 0365 if self.cursor_col > self.cols:366 self.cursor_col = self.cols367 if self.cursor_row < 0:368 self.cursor_row = 0369 if self.cursor_row >= self.rows:370 self.cursor_row = self.rows - 1371 def cursor_left_tab(self, params):372 count = params[0]373 if count == 0:374 count = 1375 if count > self.cols:376 count = self.cols377 for i in xrange(0, count):378 if (self.cursor_col % self.tab_width) == 0:379 self.cursor_col -= self.tab_width380 else:381 self.cursor_col -= self.cursor_col % self.tab_width382 if self.cursor_col < 0:383 self.cursor_col = 0384 def cursor_right_tab(self, params):385 count = params[0]386 if count == 0:387 count = 1388 if count > self.cols:389 count = self.cols390 for i in xrange(0, count):391 self.cursor_col += self.tab_width - (self.cursor_col % self.tab_width)392 if self.cursor_col > self.cols:393 self.cursor_col = self.cols394 def erase_screen(self, params):395 if (len(params) == 0) or (params[0] == 0):396 self.erase_rect(self.cursor_row, self.cursor_col, self.cursor_row + 1, self.cols)397 self.erase_rect(self.cursor_row + 1, 0, self.rows, self.cols)398 elif params[0] == 1:399 self.erase_rect(0, 0, self.cursor_row, self.cols)400 self.erase_rect(self.cursor_row, 0, self.cursor_row + 1, self.cursor_col + 1)401 elif params[0] == 2:402 self.erase_rect(0, 0, self.rows, self.cols)403 self.cursor_row = 0404 self.cursor_col = 0405 def erase_line(self, params):406 if (len(params) == 0) or (params[0] == 0):407 self.erase_rect(self.cursor_row, self.cursor_col, self.cursor_row + 1, self.cols)408 elif params[0] == 1:409 self.erase_rect(self.cursor_row, 0, self.cursor_row + 1, self.cursor_col + 1)410 elif params[0] == 2:411 self.erase_rect(self.cursor_row, 0, self.cursor_row + 1, self.cols)412 def scroll_region(self, params):413 if len(params) < 2:414 return415 self.scroll_top = params[0] - 1416 self.scroll_bottom = params[1] - 1417 if self.scroll_top < 0:418 self.scroll_top = 0419 if self.scroll_top >= self.rows:420 self.scroll_top = self.rows - 1421 if self.scroll_bottom < 0:422 self.scroll_bottom = 0423 if self.scroll_bottom >= self.rows:424 self.scroll_bottom = self.rows - 1425 def insert_lines(self, params):426 count = params[0]427 if count == 0:428 count = 1429 if count == 0:430 return431 if (self.cursor_row < self.scroll_top) or (self.cursor_row > self.scroll_bottom):432 return433 if count > ((self.scroll_bottom + 1) - self.cursor_row):434 count = (self.scroll_bottom + 1) - self.cursor_row435 erased_screen = []436 erased_rendition = []437 for i in xrange(0, count):438 erased_screen.append(self.screen.pop((self.scroll_bottom + 1) - count))439 erased_rendition.append(self.rendition.pop((self.scroll_bottom + 1) - count))440 for j in xrange(0, self.cols):441 erased_screen[i][j] = u' '442 erased_rendition[i][j] = self.active_rendition443 for i in xrange(0, count):444 self.screen.insert(self.cursor_row, erased_screen[i])445 self.rendition.insert(self.cursor_row, erased_rendition[i])446 self.invalidate()447 def delete_lines(self, params):448 count = params[0]449 if count == 0:450 count = 1451 if (self.cursor_row < self.scroll_top) or (self.cursor_row > self.scroll_bottom):452 return453 if count == 0:454 return455 if count > ((self.scroll_bottom + 1) - self.cursor_row):456 count = (self.scroll_bottom + 1) - self.cursor_row457 erased_screen = []458 erased_rendition = []459 for i in xrange(0, count):460 erased_screen.append(self.screen.pop(self.cursor_row))461 erased_rendition.append(self.rendition.pop(self.cursor_row))462 for j in xrange(0, self.cols):463 erased_screen[i][j] = u' '464 erased_rendition[i][j] = self.active_rendition465 for i in xrange(0, count):466 self.screen.insert((self.scroll_bottom + 1) - count, erased_screen[i])467 self.rendition.insert((self.scroll_bottom + 1) - count, erased_rendition[i])468 self.invalidate()469 def scroll_up_lines(self, params):470 count = params[0]471 if count == 0:472 count = 1473 if count == 0:474 return475 if count > ((self.scroll_bottom + 1) - self.scroll_top):476 count = (self.scroll_bottom + 1) - self.scroll_top477 erased_screen = []478 erased_rendition = []479 for i in xrange(0, count):480 erased_screen.append(self.screen.pop(self.scroll_top))481 erased_rendition.append(self.rendition.pop(self.scroll_top))482 for j in xrange(0, self.cols):483 erased_screen[i][j] = u' '484 erased_rendition[i][j] = self.active_rendition485 for i in xrange(0, count):486 self.screen.insert((self.scroll_bottom + 1) - count, erased_screen[i])487 self.rendition.insert((self.scroll_bottom + 1) - count, erased_rendition[i])488 self.invalidate()489 def scroll_down_lines(self, params):490 count = params[0]491 if count == 0:492 count = 1493 if count == 0:494 return495 if count > ((self.scroll_bottom + 1) - self.scroll_top):496 count = (self.scroll_bottom + 1) - self.scroll_top497 erased_screen = []498 erased_rendition = []499 for i in xrange(0, count):500 erased_screen.append(self.screen.pop((self.scroll_bottom + 1) - count))501 erased_rendition.append(self.rendition.pop((self.scroll_bottom + 1) - count))502 for j in xrange(0, self.cols):503 erased_screen[i][j] = u' '504 erased_rendition[i][j] = self.active_rendition505 for i in xrange(0, count):506 self.screen.insert(self.scroll_top, erased_screen[i])507 self.rendition.insert(self.scroll_top, erased_rendition[i])508 self.invalidate()509 def insert_chars(self, params):510 count = params[0]511 if count == 0:512 count = 1513 if count > (self.cols - self.cursor_col):514 count = self.cols - self.cursor_col515 for i in xrange(self.cols - 1, self.cursor_col + count - 1, -1):516 self.screen[self.cursor_row][i] = self.screen[self.cursor_row][i - count]517 self.rendition[self.cursor_row][i] = self.rendition[self.cursor_row][i - count]518 self.erase_rect(self.cursor_row, self.cursor_col, self.cursor_row + 1, self.cursor_col + count)519 self.dirty.add(self.cursor_row)520 def delete_chars(self, params):521 count = params[0]522 if count == 0:523 count = 1524 if count > (self.cols - self.cursor_col):525 count = self.cols - self.cursor_col526 for i in xrange(self.cursor_col, self.cols - count):527 self.screen[self.cursor_row][i] = self.screen[self.cursor_row][i + count]528 self.rendition[self.cursor_row][i] = self.rendition[self.cursor_row][i + count]529 self.erase_rect(self.cursor_row, self.cols - count, self.cursor_row + 1, self.cols)530 self.dirty.add(self.cursor_row)531 def erase_chars(self, params):532 count = params[0]533 if count == 0:534 count = 1535 self.erase_rect(self.cursor_row, self.cursor_col, self.cursor_row + 1, self.cursor_col + count)536 def graphic_rendition(self, params):537 i = 0538 while i < len(params):539 val = params[i]540 if val == 0:541 # Default rendition542 self.active_rendition = 0543 elif (val >= 1) and (val <= 9):544 # Set style545 self.active_rendition &= ~0xff546 self.active_rendition |= 1 << (val - 1)547 elif (val >= 21) and (val <= 29):548 # Clear style549 self.active_rendition &= ~(1 << (val - 21))550 elif (val >= 30) and (val <= 37):551 # Normal foreground color552 self.active_rendition &= ~(0x00ff0000 | TerminalEmulator.RENDITION_FOREGROUND_256)553 self.active_rendition |= (val - 29) << 16554 elif val == 38:555 if ((i + 2) < len(params)) and (params[i + 1] == 5):556 # 256-color foreground557 self.active_rendition &= ~0x00ff0000558 self.active_rendition |= TerminalEmulator.RENDITION_FOREGROUND_256559 self.active_rendition |= (params[i + 2] & 0xff) << 16560 i += 2561 elif val == 39:562 # Default foreground color563 self.active_rendition &= ~(0x00ff0000 | TerminalEmulator.RENDITION_FOREGROUND_256)564 elif (val >= 40) and (val <= 47):565 # Normal background color566 self.active_rendition &= ~(0xff000000 | TerminalEmulator.RENDITION_BACKGROUND_256)567 self.active_rendition |= (val - 39) << 24568 elif val == 48:569 if ((i + 2) < len(params)) and (params[i + 1] == 5):570 # 256-color background571 self.active_rendition &= ~0xff000000572 self.active_rendition |= TerminalEmulator.RENDITION_BACKGROUND_256573 self.active_rendition |= (params[i + 2] & 0xff) << 24574 i += 2575 elif val == 49:576 # Default background color577 self.active_rendition &= ~(0xff000000 | TerminalEmulator.RENDITION_BACKGROUND_256)578 elif (val >= 90) and (val <= 97):579 # High intensity foreground color580 self.active_rendition &= ~(0x00ff0000 | TerminalEmulator.RENDITION_FOREGROUND_256)581 self.active_rendition |= (val - 81) << 16582 elif (val >= 100) and (val <= 107):583 # High intensity background color584 self.active_rendition &= ~(0xff000000 | TerminalEmulator.RENDITION_BACKGROUND_256)585 self.active_rendition |= (val - 91) << 16586 else:587 print "Unsupported graphic rendition %d" % val588 i += 1589 def set_option(self, params):590 for option in params:591 if option == 4: # Insert mode592 self.insert_mode = True593 def clear_option(self, params):594 for option in params:595 if option == 4: # Insert mode596 self.insert_mode = False597 def set_private_option(self, params):598 for option in params:599 if option == 1: # Cursor key setting600 self.application_cursor_keys = True601 if option == 25: # Cursor visibility602 self.cursor_visible = True603 if ((option == 47) or (option == 1049)) and (not self.alt_screen): # Alternate screen buffer604 self.screen, self.other_screen = self.other_screen, self.screen605 self.rendition, self.other_rendition = self.other_rendition, self.rendition606 self.saved_normal_cursor_row = self.cursor_row607 self.saved_normal_cursor_col = self.cursor_col608 self.cursor_row = self.saved_alt_cursor_row609 self.cursor_col = self.saved_alt_cursor_col610 self.alt_screen = True611 self.invalidate()612 def clear_private_option(self, params):613 for option in params:614 if option == 1: # Cursor key setting615 self.application_cursor_keys = False616 if option == 25: # Cursor visibility617 self.cursor_visible = False618 if ((option == 47) or (option == 1049)) and (self.alt_screen): # Alternate screen buffer619 self.screen, self.other_screen = self.other_screen, self.screen620 self.rendition, self.other_rendition = self.other_rendition, self.rendition621 self.saved_alt_cursor_row = self.cursor_row622 self.saved_alt_cursor_col = self.cursor_col623 self.cursor_row = self.saved_normal_cursor_row624 self.cursor_col = self.saved_normal_cursor_col625 self.alt_screen = False626 self.invalidate()627 def device_attr(self, params):628 self.response("\033[?1;2c")629 def device_secondary_attr(self, params):630 self.response("\033[>0;1;0c")631 def device_status(self, params):632 if params[0] == 5:633 self.response("\033[0n") # OK634 elif params[0] == 6:635 self.response("\033[%d;%dR" % (self.cursor_row + 1, self.cursor_col + 1))636 def soft_reset(self, params):637 self.active_rendition = 0638 self.cursor_visible = True639 self.tab_width = 8640 self.scroll_top = 0641 self.scroll_bottom = self.rows - 1642 self.line_draw = False643 def parse_params(self, params):644 if len(params) == 0:645 result = []646 else:647 try:648 result = [int(i) for i in params.split(u';')]649 except ValueError:650 print "Invalid parameters '%s'" % params651 return []652 return result653 def process_escape(self, sequence):654 if (sequence == u'=') or (sequence == u'>'):655 # Numpad handling, just ignore it656 return657 if sequence == u'c':658 # Terminal reset659 self.active_rendition = 0660 self.erase_rect(0, 0, self.rows, self.cols)661 self.cursor_row = 0662 self.cursor_col = 0663 self.saved_cursor_row = 0664 self.saved_cursor_col = 0665 self.invalidate()666 return667 if sequence == u'7':668 # Save cursor669 self.saved_cursor_row = self.cursor_row670 self.saved_cursor_col = self.cursor_col671 return672 if sequence == u'8':673 # Restore cursor674 self.cursor_row = self.saved_cursor_row675 self.cursor_col = self.saved_cursor_col676 return677 if sequence == u'D':678 self.line_feed()679 return680 if sequence == u'E':681 self.newline()682 return683 if sequence == u'M':684 self.reverse_line_feed()685 return686 if sequence[0] != u'[':687 print "Unhandled escape sequence '%s'" % sequence688 return689 params = sequence[1:-1]690 mode = sequence[-1]691 if (len(params) > 0) and (params[0] == u'?'):692 mode = u'?' + mode693 params = params[1:]694 if (len(params) > 0) and (params[0] == u'>'):695 mode = u'>' + mode696 params = params[1:]697 if (len(params) > 0) and (params[0] == u'!'):698 mode = u'!' + mode699 params = params[1:]700 params = self.parse_params(params)701 if len(params) == 0:702 params = [0]703 if mode in self.escape_sequences:704 self.escape_sequences[mode](params)705 else:706 print "Unhandled escape sequence '%s'" % sequence707 def start_window_title(self, sequence):708 params = self.parse_params(sequence[1:-1])709 if (len(params) == 0) or (params[0] == 0) or (params[0] == 2):710 # Setting window name711 self.ignored_window_title = False712 else:713 # Setting icon name, just ignore714 self.ignored_window_title = True715 def process(self, data):716 for raw_ch in data:717 if self.utf8_len == 0:718 if ord(raw_ch) < 128:719 ch = unicode(raw_ch)720 elif ord(raw_ch) < 0xc0:721 # Unexpected continuation character722 ch = unichr(ord(raw_ch))723 elif ord(raw_ch) < 0xe0:724 self.utf8_buffer = raw_ch725 self.utf8_len = 1726 elif ord(raw_ch) < 0xf0:727 self.utf8_buffer = raw_ch728 self.utf8_len = 2729 elif ord(raw_ch) < 0xf8:730 self.utf8_buffer = raw_ch731 self.utf8_len = 3732 elif ord(raw_ch) < 0xfc:733 self.utf8_buffer = raw_ch734 self.utf8_len = 4735 elif ord(raw_ch) < 0xfe:736 self.utf8_buffer = raw_ch737 self.utf8_len = 5738 else:739 # Invalid first byte740 ch = unichr(ord(raw_ch))741 else:742 if (ord(raw_ch) & 0xc0) != 0x80:743 # Invalid continuation character744 ch = unichr(ord(raw_ch))745 self.utf8_len = 0746 else:747 self.utf8_buffer += raw_ch748 self.utf8_len -= 1749 if self.utf8_len == 0:750 ch = unicode(self.utf8_buffer, 'utf8', 'replace')751 if self.utf8_len > 0:752 continue753 # Check for combining characters754 try:755 if (unicodedata.combining(ch) != 0) and (self.cursor_col > 0):756 # Combining character, so combine it with the previously written character757 last_ch = self.screen[self.cursor_row][self.cursor_col - 1]758 combined = unicodedata.normalize("NFC", last_ch + ch)759 if len(combined) == 1:760 # Successful combine, write out new character761 self.screen[self.cursor_row][self.cursor_col - 1] = combined762 self.dirty.add(self.cursor_row)763 continue764 except TypeError:765 # Invalid character766 ch = u' '767 if self.window_title_mode:768 if ch == u'\007': # Bell character ends window title769 if self.title_callback and not self.ignored_window_title:770 self.title_callback(self.unprocessed_input)771 self.unprocessed_input = u""772 self.window_title_mode = False773 else:774 self.unprocessed_input += ch775 elif ch in self.special_chars:776 self.special_chars[ch]()777 elif self.escape_mode:778 self.unprocessed_input += ch779 if len(self.unprocessed_input) == 1:780 if (ch != u'[') and (ch != u']') and (ch not in self.charset_escapes):781 # Special type of escape sequence, no parameters782 self.process_escape(self.unprocessed_input)783 self.unprocessed_input = u""784 self.escape_mode = False785 elif (len(self.unprocessed_input) == 2) and (self.unprocessed_input[0] in self.charset_escapes):786 if self.unprocessed_input == "(0":787 # Select line drawing character set788 self.line_draw = True789 else:790 # Other character set escape, just use UTF8791 self.line_draw = False792 self.unprocessed_input = u""793 self.escape_mode = False794 elif (ch >= u'@') and (ch <= u'~'):795 # Ending character found, process sequence796 self.process_escape(self.unprocessed_input)797 self.unprocessed_input = u""798 self.escape_mode = False799 else:800 # Parameter character, add to pending string801 if self.unprocessed_input.startswith(u']') and (ch == u';'):802 # Setting window title, wait for bell character to finish803 self.start_window_title(self.unprocessed_input)804 self.unprocessed_input = u""805 self.escape_mode = False806 self.window_title_mode = True807 elif ch == u'\033':808 self.escape()809 else:810 self.write_char(ch)811 if self.update_callback:812 self.update_callback()813 def get_dirty_lines(self):814 result = self.dirty815 self.dirty = set()...
main.py
Source:main.py
...34def waiting(css_selector, time=configs['waiting_time']):35 return WebDriverWait(driver, time).until(36 EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))37 )38def scroll_bottom():39 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")40# In[7]:41scroll_bottom()42# In[8]:43# button apply now44# waiting(configs['css']['apply_now_btn']).click()45# In[9]:46scroll_bottom()47# button login or create account48# find_elements(configs['css']['login_btn'])[-1].click()49# In[10]:50# switch tab51# driver.switch_to.window(driver.window_handles[-1])52# In[11]:53scroll_bottom()54# username input55waiting(configs['css']['username_txt']).send_keys(configs['authentication']['username'])56waiting(configs['css']['password_txt']).send_keys(configs['authentication']['password'])57waiting(configs['css']['submit_btn']).click() # button click submit58# # Äợi á» Äây59# In[33]:60configs['submit_time']61# In[34]:62def check():63 now = datetime.now()64 return (now.hour >= configs['submit_time']['hour']) and (now.minute >= configs['submit_time']['minute'])65print("Äợi má»t chút")66while not check():67 time.sleep(1)68 69print("Continue")70# In[14]:71scroll_bottom()72# button submit73waiting(configs['css']['submit_process_btn']).click()74# In[16]:75waiting('input[type=checkbox]')76# list tick button77driver.execute_script("document.querySelectorAll('input[type=checkbox]').forEach((e) => e.click())")78# In[17]:79find_element('input[value=SUBMIT]').click()80# In[18]:81# pay now button82waiting('div[align=center] > table > tbody > tr > td > a').click()83# In[19]:84scroll_bottom()85# button next step86waiting(configs['css']['next_step_btn']).click()87# In[20]:88scroll_bottom()89# payer name90waiting(configs['css']['payer_name_txt']).send_keys(configs['authentication']['payer_name'])91waiting(configs['css']['ok_btn']).click() # button ok92# In[21]:93scroll_bottom()94# payment information95waiting(configs['css']['card_number_txt']).send_keys(configs['payment']['card_number'])96waiting(configs['css']['expirydate_txt']).send_keys(configs['payment']['expirydate'])97waiting(configs['css']['csc_txt']).send_keys(configs['payment']['csc'])98waiting(configs['css']['card_holder_txt']).send_keys(configs['payment']['cardholder_name'])99# button pay...
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!!