乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Selenium WebDriver 中鼠標(biāo)和鍵盤事件分析及擴展

       小豬窩969 2015-07-15

      概念

      在使用 Selenium WebDriver 做自動化測試的時候,會經(jīng)常模擬鼠標(biāo)和鍵盤的一些行為。比如使用鼠標(biāo)單擊、雙擊、右擊、拖拽等動作;或者鍵盤輸入、快捷鍵使用、組合鍵使用等模擬鍵盤的操作。在 WebDeriver 中,有一個專門的類來負責(zé)實現(xiàn)這些測試場景,那就是 Actions 類,在使用該類的過程中會配合使用到 Keys 枚舉以及 Mouse、 Keyboard、CompositeAction 等類。

      其次,在實際測試過程中,可能會遇到某些按鍵沒辦法使用 Actions、Keys 等類來實現(xiàn)的情況。 比如通過使用 Alt+PrtSc 組合鍵來實現(xiàn)截取屏幕當(dāng)前活動窗口的圖像,在 Keys 枚舉中,因為沒有枚舉出 PrtSc 鍵,所以沒辦法通過 Action 的 KeyDown(Keys) 來模擬按下這個動作。

      再次是在自動化測試中,可能會遇到一些附件、文件上傳的場景,或者是多文件上傳,這些在 Selenium2.0 之后,可以直接使用 WebElement 類的 sendKeys() 方法來實現(xiàn)。

      下面就分別介紹這些情況的具體使用。

      回頁首

      鼠標(biāo)點擊操作

      鼠標(biāo)點擊事件有以下幾種類型:

      清單 1. 鼠標(biāo)左鍵點擊
       Actions action = new Actions(driver);action.click();// 鼠標(biāo)左鍵在當(dāng)前停留的位置做單擊操作 
      action.click(driver.findElement(By.name(element)))// 鼠標(biāo)左鍵點擊指定的元素
      清單 2. 鼠標(biāo)右鍵點擊
       Actions action = new Actions(driver); 
       action.contextClick();// 鼠標(biāo)右鍵在當(dāng)前停留的位置做單擊操作 
      action.contextClick(driver.findElement(By.name(element)))// 鼠標(biāo)右鍵點擊指定的元素
      清單 3. 鼠標(biāo)雙擊操作
       Actions action = new Actions(driver); 
       action.doubleClick();// 鼠標(biāo)在當(dāng)前停留的位置做雙擊操作 
      action.doubleClick(driver.findElement(By.name(element)))// 鼠標(biāo)雙擊指定的元素
      清單 4. 鼠標(biāo)拖拽動作
       Actions action = new Actions(driver); 
      // 鼠標(biāo)拖拽動作,將 source 元素拖放到 target 元素的位置。
       action.dragAndDrop(source,target);
      // 鼠標(biāo)拖拽動作,將 source 元素拖放到 (xOffset, yOffset) 位置,其中 xOffset 為橫坐標(biāo),yOffset 為縱坐標(biāo)。
      action.dragAndDrop(source,xOffset,yOffset);

      在這個拖拽的過程中,已經(jīng)使用到了鼠標(biāo)的組合動作,首先是鼠標(biāo)點擊并按住 (click-and-hold) source 元素,然后執(zhí)行鼠標(biāo)移動動作 (mouse move),移動到 target 元素位置或者是 (xOffset, yOffset) 位置,再執(zhí)行鼠標(biāo)的釋放動作 (mouse release)。所以上面的方法也可以拆分成以下的幾個執(zhí)行動作來完成:

      action.clickAndHold(source).moveToElement(target).perform(); 
       action.release();
      清單 5. 鼠標(biāo)懸停操作
       Actions action = new Actions(driver); 
       action.clickAndHold();// 鼠標(biāo)懸停在當(dāng)前位置,既點擊并且不釋放
       action.clickAndHold(onElement);// 鼠標(biāo)懸停在 onElement 元素的位置

      action.clickAndHold(onElement) 這個方法實際上是執(zhí)行了兩個動作,首先是鼠標(biāo)移動到元素 onElement,然后再 clickAndHold, 所以這個方法也可以寫成 action.moveToElement(onElement).clickAndHold()。

      清單 6. 鼠標(biāo)移動操作
       Actions action = new Actions(driver); 
       action.moveToElement(toElement);// 將鼠標(biāo)移到 toElement 元素中點
      // 將鼠標(biāo)移到元素 toElement 的 (xOffset, yOffset) 位置,
      //這里的 (xOffset, yOffset) 是以元素 toElement 的左上角為 (0,0) 開始的 (x, y) 坐標(biāo)軸。
       action.moveToElement(toElement,xOffset,yOffset)
      // 以鼠標(biāo)當(dāng)前位置或者 (0,0) 為中心開始移動到 (xOffset, yOffset) 坐標(biāo)軸
       action.moveByOffset(xOffset,yOffset);

      action.moveByOffset(xOffset,yOffset) 這里需要注意,如果 xOffset 為負數(shù),表示橫坐標(biāo)向左移動,yOffset 為負數(shù)表示縱坐標(biāo)向上移動。而且如果這兩個值大于當(dāng)前屏幕的大小,鼠標(biāo)只能移到屏幕最邊界的位置同時拋出 MoveTargetOutOfBoundsExecption 的異常。

      鼠標(biāo)移動操作在測試環(huán)境中比較常用到的場景是需要獲取某元素的 flyover/tips,實際應(yīng)用中很多 flyover 只有當(dāng)鼠標(biāo)移動到這個元素之后才出現(xiàn),所以這個時候通過執(zhí)行 moveToElement(toElement) 操作,就能達到預(yù)期的效果。但是根據(jù)我個人的經(jīng)驗,這個方法對于某些特定產(chǎn)品的圖標(biāo),圖像之類的 flyover/tips 也不起作用,雖然在手動操作的時候移動鼠標(biāo)到這些圖標(biāo)上面可以出現(xiàn) flyover, 但是當(dāng)使用 WebDriver 來模擬這一移動操作時,雖然方法成功執(zhí)行了,但是 flyover 卻出不來。所以在實際應(yīng)用中,還需要對具體的產(chǎn)品頁面做相應(yīng)的處理。

      清單 7. 鼠標(biāo)釋放操
       Actions action = new Actions(driver); 
       action.release();// 釋放鼠標(biāo)

      回頁首

      鍵盤模擬操作

      對于鍵盤的模擬操作,Actions 類中有提供 keyUp(theKey)、keyDown(theKey)、sendKeys(keysToSend) 等方法來實現(xiàn)。鍵盤的操作有普通鍵盤和修飾鍵盤(Modifier Keys, 下面的章節(jié)將講到修飾鍵的概念)兩種 :

      1. 對于普通鍵盤,使用 sendKeys(keysToSend) 就可以實現(xiàn),比如按鍵 TAB、Backspace 等。

      清單 8. 普通鍵盤模擬 sendKeys(keysToSend)
       Actions action = new Actions(driver); 
       action.sendKeys(Keys.TAB);// 模擬按下并釋放 TAB 鍵
       action.sendKeys(Keys.SPACE);// 模擬按下并釋放空格鍵
      /***
      針對某個元素發(fā)出某個鍵盤的按鍵操作,或者是輸入操作,
      比如在 input 框中輸入某個字符也可以使用這個方法。這個方法也可以拆分成:
      action.click(element).sendKeys(keysToSend)。
      */
       action.sendKeys(element,keysToSend);

      注意除了 Actions 類有 sendKeys(keysToSend)方法外,WebElement 類也有一個 sendKeys(keysToSend)方法,這兩個方法對于一般的輸入操作基本上相同,不同點在于以下幾點:

      • Actions 中的 sendKeys(keysToSend) 對于修飾鍵 (Modifier Keys) 的調(diào)用并不會釋放,也就是說當(dāng)調(diào)用 actions.sendKeys(Keys.ALT); actions.sendKeys(Keys.CONTROL); action.sendKeys(Keys.SHIFT); 的時候,相當(dāng)于調(diào)用 actions.keyDown(keysToSend),而如果在現(xiàn)實的應(yīng)用中想要模擬按下并且釋放這些修飾鍵,應(yīng)該再調(diào)用 action.sendKeys(keys.NULL) 來完成這個動作。
      • 其次就是當(dāng) Actions 的 sendKeys(keysToSend) 執(zhí)行完之后,焦點就不在當(dāng)前元素了。所以我們可以使用 sendKeys(Keys.TAB) 來切換元素的焦點,從而達到選擇元素的作用,這個最常用到的場景就是在用戶名和密碼的輸入過程中。
      • 第三點,在 WebDriver 中,我們可以使用 WebElement 類的 sendKeys(keysToSend) 來上傳附件,比如 element.sendKeys(“C:\\test\\uploadfile\\test.jpg”); 這個操作將 test.jpg 上傳到服務(wù)器,但是使用:
      Actions action = New Actions(driver); 
       action.sendKeys(element,“C:\\test\\upload\\test.jpg”); 
      action.click(element).sendKeys(“C:\\test\\upload\\test.jpg”);

      這種方式是上傳不成功的,雖然 WebDriver 在執(zhí)行這條語句的時候不會出錯,但是實際上并沒有將文件上傳。所以要上傳文件,還是應(yīng)該使用前面一種方式。

      2.對于修飾鍵(Modifier keys),一般都是跟普通鍵組合使用的。比如 Ctrl+a、Alt+F4、 Shift+Ctrl+F 等等。

      • 這里先解釋一下修飾鍵的概念,修飾鍵是鍵盤上的一個或者一組特別的鍵,當(dāng)它與一般按鍵同時使用的時候,用來臨時改變一般鍵盤的普通行為。對于單獨按下修飾鍵本身一般不會觸發(fā)任何鍵盤事件。在個人計算機上的鍵盤上,有以下幾個修飾鍵:Shift、Ctrl、Alt(Option)、AltGr、Windows logo、Command、FN(Function)。但是在 WebDriver 中,一般的修飾鍵指前面三個。你可以點擊下面的 Wiki 鏈接去了解更多有關(guān)修飾鍵的信息,Modifier key。
      • 回到上面的話題,在 WebDriver 中對于修飾鍵的使用需要用到 KeyDown(theKey)、keyUp(theKey) 方法來操作。
      清單 9. 修飾鍵方法 KeyDown(theKey)、keyUp(theKey)
       Actions action = new Actions(driver); 
       action.keyDown(Keys.CONTROL);// 按下 Ctrl 鍵
       action.keyDown(Keys.SHIFT);// 按下 Shift 鍵
       action.keyDown(Key.ALT);// 按下 Alt 鍵
       action.keyUp(Keys.CONTROL);// 釋放 Ctrl 鍵
       action.keyUp(Keys.SHIFT);// 釋放 Shift 鍵
       action.keyUp(Keys.ALT);// 釋放 Alt 鍵

      所以要通過 Alt+F4 來關(guān)閉當(dāng)前的活動窗口,可以通過下面語句來實現(xiàn):action.keyDown(Keys.ALT).keyDown(Keys.F4).keyUp(Keys.ALT).perform();

      而如果是對于像鍵盤上面的字母鍵 a,b,c,d... 等的組合使用,可以通過以下語句實現(xiàn) :action.keyDown(Keys.CONTROL).sednKeys(“a”).perform();

      在 WebDriver API 中,KeyDown(Keys theKey)、KeyUp(Keys theKey) 方法的參數(shù)只能是修飾鍵:Keys.SHIFT、Keys.ALT、Keys.CONTROL, 否者將拋出 IllegalArgumentException 異常。 其次對于 action.keyDown(theKey) 方法的調(diào)用,如果沒有顯示的調(diào)用 action.keyUp(theKey) 或者 action.sendKeys(Keys.NULL) 來釋放的話,這個按鍵將一直保持按住狀態(tài)。

      回頁首

      使用 Robot 類來操作 Keys 沒有枚舉出來的按鍵操作

      1.在 WebDriver 中,Keys 枚舉出了鍵盤上大多數(shù)的非字母類按鍵,從 F1 到 F10,NUMPAD0 到 NUMPAD9、ALT\TAB\CTRL\SHIFT 等等,你可以通過以下鏈接查看 Keys 枚舉出來的所有按鍵,Enum Keys。 但是并沒有列出鍵盤上的所有按鍵,比如字母鍵 a、b、c、d … z,一些符號鍵比如:‘ {}\[] ’、‘ \ ’、‘?!?、‘ ? ’、‘:’、‘ + ’、‘ - ’、‘ = ’、、‘“”’,還有一些不常用到的功能鍵如 PrtSc、ScrLk/NmLk。對于字母鍵和符號鍵,前面我們已經(jīng)提到可以直接使用 sendKeys(“a”),sendKeys(“/”) 的方式來觸發(fā)這些鍵盤事件。而對于一些功能組合鍵,如 Fn + NmLk 來關(guān)閉或者打開數(shù)字鍵,或者 Alt+PrtSC 來抓取當(dāng)前屏幕的活動窗口并保存到圖片,通過 WebDriver 的 Keys 是沒辦法操作的。 這個時候我們就需要用到 Java 的 Robot 類來實現(xiàn)對這類組合鍵的操作了。

      2.下面就以對 Alt+PrtSc 為例介紹一下 Robot 對鍵盤的操作。如代碼清單 10。

      清單 10. 通過 Robot 發(fā)出組合鍵動作
       /** 
       * 
       * @Description: 這個方法用來模擬發(fā)送組合鍵 Alt + PrtSc, 當(dāng)組合鍵盤事件執(zhí)行之后,屏幕上的活動窗口
       * 就被截取并且存儲在剪切板了。 接下來就是通過讀取剪切板數(shù)據(jù)轉(zhuǎn)換成 Image 圖像對象并保存到本地。
       * @param filename : 要保存的圖像的名稱
       */ 
       public static void sendComposeKeys(String fileName) throws Exception { 
      		 // 構(gòu)建 Robot 對象,用來操作鍵盤
      		 Robot robot = new Robot(); 
      		 // 模擬按下鍵盤動作,這里通過使用 KeyEvent 類來獲取對應(yīng)鍵盤(ALT)的虛擬鍵碼
       robot.keyPress(java.awt.event.KeyEvent.VK_ALT); 
      		 // 按下 PrtSC 鍵
      		 robot.keyPress(java.awt.event.KeyEvent.VK_PRINTSCREEN); 
      		 // 釋放鍵盤動作,當(dāng)這個動作完成之后,模擬組合鍵 Alt + PrtSC 的過程就已經(jīng)完成,
      //此時屏幕活動窗口就一被截取并存入到剪切板
      		 robot.keyRelease(java.awt.event.KeyEvent.VK_ALT); 
      		 // 獲取系統(tǒng)剪切板實例
       Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard(); 
      		 // 通過 getContents() 方法就可以將剪切板內(nèi)容獲取并存入 Transferable 對象中
      		 Transferable data = sysc.getContents(null); 
      		 if (data != null) { 
      /***
      判斷從剪切板獲取的對象內(nèi)容是否為 Java Image 類, 如果是將直接轉(zhuǎn)化為 Image 對象。
      到此為止,我們就從發(fā)出組合鍵到抓取活動窗口,再讀取剪切板并存入 Image 對象的過程
      就完成了,接下來要做的就是需要將 Image 對象保存到本地。
      */
      			 if (data.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
      				 Image image = (Image) data 
      						 .getTransferData(DataFlavor.imageFlavor); 
      				 writeImageToFile(image, fileName); 
      			 } 
      		 } 
      	 }

      Robot 類對鍵盤的處理是通過 keyPress(int keycode)、keyRelease(int keycode) 方法來實現(xiàn)的,其中他們需要的參數(shù)是鍵盤按鍵對應(yīng)的虛擬鍵碼,虛擬鍵碼的值可以通過 KeyEvent 類來獲取。在 Java API 中對于虛擬鍵碼的解釋如下: 虛擬鍵碼用于報告按下了鍵盤上的哪個鍵,而不是一次或多次鍵擊組合生成的字符(如 "A" 是由 shift + "a" 生成的)。 例如,按下 Shift 鍵會生成 keyCode 為 VK_SHIFT 的 KEY_PRESSED 事件,而按下 'a' 鍵將生成 keyCode 為 VK_A 的 KEY_PRESSED 事件。釋放 'a' 鍵后,會激發(fā) keyCode 為 VK_A 的 KEY_RELEASED 事件。另外,還會生成一個 keyChar 值為 'A' 的 KEY_TYPED 事件。 按下和釋放鍵盤上的鍵會導(dǎo)致(依次)生成以下鍵事件:

      KEY_PRESSED

      KEY_TYPED(只在可生成有效 Unicode 字符時產(chǎn)生。)

      KEY_RELEASED

      所以當(dāng)測試中需要用到按下鍵盤 Alt+PrtSc 鍵的時候,只需要執(zhí)行代碼清單 10 中兩個 keyPress() 和一個 keyRelease() 方法即可。

      3.當(dāng)這兩個按鍵執(zhí)行結(jié)束之后,屏幕上面的活動窗口已經(jīng)保存到剪切板中。如果需要將其保存本地圖片,只需要從剪切板讀取并通過 JPEGImageEncoder 類或者 ImageIO 類將其寫入本地即可。

      清單 11. 使用 JPEGImageEncoder 將 Image 對象保存到本地
       /** 
       * 
       * @Description: 這個方法用來將 Image 對象保存到本地,主要是通過 JPEGImageEncoder 類來實現(xiàn)圖像的
       * 保存
       * @param image : 要保存的 Image 對象
       * @param filename : 保存圖片的文件名稱
       */ 
       public static void writeImageToFile(Image image, String fileName) { 
      		 try { 
      			 // 獲取 Image 對象的寬度和高度, 這里的參數(shù)為 null 表示不需要通知任何觀察者
       int width = image.getWidth(null);
      			 int height = image.getHeight(null); 
      			 BufferedImage bi = new BufferedImage(width, height, 
      					 BufferedImage.TYPE_INT_RGB); 
       // 通過 BufferedImage 繪制圖像并保存在其對象中
      			 bi.getGraphics().drawImage(image, 0, 0, null); 
      			 // 構(gòu)建圖像名稱及保存路徑
      			 String name = Const.DIRECTORY + fileName + Const.FORMAT; 
      			 File dir = new File(Const.DIRECTORY); 
      			 if (!dir.exists()) { 
      				 dir.mkdir(); 
      			 } 
      			 FileOutputStream out = new FileOutputStream(name); 
      			 @SuppressWarnings("restriction") 
      			 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 
       encoder.encode(bi); 
      			 out.flush(); 
       out.close(); 
      		 } catch (Exception e) { 
      			 e.printStackTrace(); 
      		 } 
      	 }

      代碼清單 11 是通過 JPEGImageEncoder 類將 Image 對象寫到本地文件流,注意 Image 對象是在代碼清單 10 中的如下語句獲取到的:

      		 Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard(); 
      		 Transferable data = sysc.getContents(null); 
      		 if (data != null) { 
      			 if (data.isDataFlavorSupported(DataFlavor.imageFlavor)) { 
      				 Image image = (Image) data 
      						 .getTransferData(DataFlavor.imageFlavor); 
      				 writeImageToFile(image, fileName); 
      			 } 
      		 }
      清單 12. 使用 ImageIO 將 Image 對象保存到本地
       /** 
       * 
       * @Description: 通過使用 ImageIO 類來保存 Image 對象為本地圖片
       * @param image : 需要保存的 Image 對象
       * @param filename : 文件名
       */ 
       public static void saveImage(Image image, String fileName) throws Exception { 
      	 // 獲取 Image 對象的高度和寬度
      	 int width = image.getWidth(null); 
      	 int height = image.getHeight(null); 
      	 BufferedImage bi = new BufferedImage(width, height, 
      			 BufferedImage.TYPE_INT_RGB); 
      	 Graphics g = bi.getGraphics(); 
           //通過 BufferedImage 繪制圖像并保存在其對象中
      	 g.drawImage(image, 0, 0, width, height, null); 
      	 g.dispose(); 
      	 File f = new File(fileName); 
      	 // 通過 ImageIO 將圖像寫入到文件
      	 ImageIO.write(bi, "jpg", f); 
      	 }

      回頁首

      使用 sendKeys(keysToSend) 批量上傳文件

      在 Selenium2.0 之前,要上傳文件是比較麻煩的一件事件,因為點擊 Upload File 控件會彈出 Windows 窗口以提供用戶選擇文件,但是 Window 窗口已經(jīng)是瀏覽器之外的組件,所以 Selenium 本身沒辦法控制, 而必須使用 Java Robot 類來模擬鍵盤去操作剪切板實現(xiàn)上傳功能,而且及其不穩(wěn)定。 在 Selenium 2.0 之后,WebDriver 解決了這個問題。前面已經(jīng)談到過,直接使用 WebElement 類的 sendKeys(keysToSend) 方法就可以實現(xiàn)文件上傳了。但是如果想批量上傳文件,使用 element.sendKeys(“C:\\test\\upload\\test1.txt”, “C:\\test\\upload\\test2.txt”...) 方法也是不行的,它能通過執(zhí)行,但是實際上沒有上傳成功。這時可以通過循環(huán)的方式來實現(xiàn)文件的批量上傳,代碼清單 13 是我在百度云上面批量上傳文件的測試。

      清單 13. 批量上傳文件
       /** 
       * 
       * @Description: 在百度云上測試文件批量上傳功能,主要是通過循環(huán)的方式去做單一
       * 的上傳動作 , 登陸過程已經(jīng)去掉
       */ 
       @Test 
       public void test_mutilUploadFile() throws Exception { 
       System.out.println("upload start"); 
      		 // 獲取上傳控件元素
       WebElement uploadButton = driver.findElement(By.name("html5uploader")); 
       // 構(gòu)建上傳文件路徑,將需要上傳的文件添加到 CharSequence 數(shù)組
       CharSequence[] files = new CharSequence[5]; 
      		 files[0] = "C:\\test\\test1.txt"; 
      		 files[1] = "C:\\test\\test2.txt"; 
      		 files[2] = "C:\\test\\test3.txt"; 
      		 files[3] = "C:\\test\\test4.txt"; 
      		 files[4] = "C:\\test\\test5.txt"; 
      		 // 循環(huán)列出每支需要上傳的文件路徑,做單一上傳動作
      		 for(CharSequence file: files){ 
       uploadButton.sendKeys(file); 
      		 } 
      		 Thread.sleep(2000); 
       System.out.println("upload end"); 
      	 }

      當(dāng)執(zhí)行結(jié)束后,效果如圖 1。

      圖 1. 批量上傳文件
      批量上傳文件

      回頁首

      結(jié)束語

      在 Selenium WebDriver 中,有了 Actions 類和 Keys 枚舉對鍵盤和鼠標(biāo)的操作已經(jīng)做的非常到位,再結(jié)合 Java 本身 Robot、KeyEvent 等類的使用,基本上可以滿足工作中遇到的對鼠標(biāo)鍵盤操作的應(yīng)用了。

      其次要注意的地方是 WebDriver 對瀏覽器的支持問題,Selenium WebDriver 支持的瀏覽器非常廣泛,從 IE、Firefox、Chrome 到 Safari 等瀏覽器, WebDriver 都有相對應(yīng)的實現(xiàn):InterntExplorerDriver、FirefoxDriver、ChromeDriver、SafariDriver、AndroidDriver、 IPhoneDriver、HtmlUnitDriver 等。根據(jù)個人的經(jīng)驗,F(xiàn)irefox 以及 Chrome 瀏覽器對 WebDriver 的支持最好了,F(xiàn)irefox 搭上 Firebug 以及 Firepath, 在寫腳本的過程中非常方便,而 ChromeDriver 是 Google 公司自己支持與維護的項目。HtmlUnitDriver 速度最快,一個純 Java 實現(xiàn)的瀏覽器。IE 比較慢,而且對于 Xpath 等支持不是很好。更多關(guān)于 Selenium WebDriver 的知識,大家可以從下面的鏈接去訪問 Selenium 官方文檔。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多